2016-07-05 2 views
1

My viewModel имеет массив под названием «Элементы». Я хочу отобразить содержимое «Items», используя привязку foreach. Все работает нормально, когда я использую обычный HTML. Но не работает с диалоговым окном, которое я создал с помощью jQueryUI.Перехват нокаута не работает с диалогом jQueryUI

HTML:

<div id="skus0"> 
    <div id="skus1"> 
    <ul data-bind="foreach: Items"> 
     <li data-bind="text:Name"></li> 
    </ul> 
    </div> 
    <input type="button" id="openQryItems" class="btn btn-info" value="Open" data-bind="click:openQueryItems" /> 
</div> 

JavaScript:

// my view model 
var viewModel = { 
    Items: [{Name:'Soap'},{Name:'Toothpaste'}] 
}; 

// JS to configure dialogue 
$("#skus1").dialog({ 
    autoOpen: false, 
    width: 500, 
    modal: true, 
    buttons: { 
    "OK": function() { 
     $(this).dialog("close"); 
    }, 
    "Cancel": function() { 
     $(this).dialog("close"); 
    } 
    } 
}); 

// for mapping my model using ko.mapping plugin 
var zub = zub || {}; 
zub.initModel = function (model) { 
    zub.cycleCountModel = ko.mapping.fromJS(model); 
    zub.cycleCountModel.openQueryItems = function() { 
    $("#skus1").dialog("open"); 
    } 
    ko.applyBindings(zub.cycleCountModel, $("#skus0")[0]); 
} 

zub.initModel(viewModel); 

Я создал скрипку здесь my fiddle

+0

@ Matt.kaaj Я должен использовать ko.mapping и пространство имен. моя модель в реальном мире очень большая, и ko.mapping действительно помогает мне в этом. – Harrobbed

ответ

2

$.fn.dialog удаляет элемент из его места в DOM и помещает его в новый контейнер ; таким образом он может создать плавающее окно. Проблема с этим случаем заключается в том, что он нарушает привязку данных, поскольку диалог DOM больше не вложен в DOM верхнего уровня данных.

Перемещение диалоговой инициализации к послеko.applyBindings позволит dialog дергать материал из DOM после списка заполняются. Конечно, это означает, что после этого момента будущие изменения все равно не будут отражены, что может быть важно, если вы хотите, чтобы открытое диалоговое окно автоматически менялось.

Если вы хотите, чтобы содержимое диалога было полностью динамическим, вы можете создать обработчик привязки; мы сделали это в нашем проекте. Вот грубый набросок того, как мы сделали это:

ko.bindingHandlers.dialog = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingCtx) { 
    var bindingValues = valueAccessor(); 
    var hasAppliedBindings = false; 
    var elem = $(element); 
    var options = { 
     id: ko.utils.unwrapObservable(bindingValues.id), 
     title: ko.utils.unwrapObservable(bindingValues.title), 
     // etc... 
     onOpen: function() { 
     if (!hasAppliedBindings) { 
      hasAppliedBindings = true; 
      var childCtx = bindingCtx.createChildContext(viewModel); 
      ko.applyBindingsToDescendants(childCtx, element); 
     } 
     } 
    }; 

    elem.dialog(options); 
    } 

    return { controlsDescendantBindings: true }; 
} 

... который мы использовали, как это:

<div data-bind="dialog: { title: 'some title', id: 'foo', ... }"> 
    <!-- dialog contents --> 
</div> 

return { controlsDescendantBindings: true } Что делает это гарантирует, что внешние привязки ничего с помощью dialog связывания не влияют обработчик. Затем мы создаем собственный привязанный к нокауту «остров» после того, как его вытащили из DOM, основываясь на исходной модели представления.

Хотя в нашем проекте мы также использовали гибридный jQuery + Knockout, я настоятельно рекомендую вам избегать этого, когда это возможно. Было так много хакеров, которые нам приходилось использовать для поддержки такого типа приложений. Самое лучшее, что вам нужно сделать, это отдать предпочтение обработчикам привязки Knockout (и я думаю, что теперь он имеет «компонентную» концепцию, с которой я не играл) над DOM-манипуляциями, чтобы избежать ошибочного управления пользовательским интерфейсом.

+0

спасибо! пошел домой и попробовал. Это работало. Все, что мне нужно было сделать, это инициализировать диалог после ko.applyBindings, как вы предложили. – Harrobbed

Смежные вопросы