Hot Towel - привязки данных элемента Dynamic Dom

Сегодня у меня возникла проблема с привязкой данных с использованием нокаута в Hot Towel API. Возьмем, к примеру, следующее...

var vm = {
    item: { entry: 'yes' }
}

return vm

и html

<div data-bind="text: item.entry"></div>

Это работает, однако, когда я изменяю js для динамического добавления div

var vm = {
    canActivate: canActivate,
    activate: activate,
    attached: attached,
    item: { entry: 'yes' }
}

return vm

function canActivate(){
     return true;
}

function activate() {
     logger.log(title + ' View Activated', null, title, true);
     return true;
}

function attached() {
     $('#page').append('<div data-bind=\"item.entry\"></div>);
}

Привязка данных не удалась. Я попытался использовать ko.cleanNode, а затем попытался повторно привязать объект DOM, но получил сообщение о невозможности повторного применения привязок. Кто-нибудь придумал решение для динамически добавляемых привязок данных DOM?


person Scott Alexander    schedule 28.04.2014    source источник
comment
Могу я спросить, почему вы хотите добавить элемент? Вы не должны делать этого при использовании нокаута. Вместо этого у вас будет список элементов, а затем нокаут отобразит их для вас, используя привязку foreach. А для добавления нового... тогда вы просто добавили бы его в список моделей представления, и все это просто работало бы и отображалось мгновенно.   -  person 4imble    schedule 28.04.2014
comment
Это то, на что я сейчас смотрю, однако это большая задача с точки зрения того, что я делаю, поскольку мой макет страницы управляется базой данных.   -  person Scott Alexander    schedule 28.04.2014


Ответы (2)


Для этого можно использовать шаблоны и метод ko.renderTemplate (см. скрипку).

HTML

<div id="page"></div>

<script type="text/html" id="appendedEntry">
    <div data-bind="text: entry"></div>
</script>

JS

var vm = {
    item: { entry: 'yes' },
    append: appendDiv
};

function appendDiv() {
    ko.renderTemplate('appendedEntry', vm.item, {}, document.getElementById('page'));    
}

ko.applyBindings(vm);

vm.append();

Вы можете узнать больше о методе ko.renderTemplate (что именно он делает и какие у него параметры) в эту статью.

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

person rwisch45    schedule 28.04.2014

Если вы хотите избежать рендеринга элемента вручную, вы можете сделать это следующим образом:

http://jsfiddle.net/Akn5T/

<ul data-bind="foreach: items">
    <li>
        <span data-bind="text: entry"> </span>
    </li>
</ul>

<button data-bind="click: add">Add new</button>

function vm() {
    var items = ko.observableArray([
        { entry: 'yes' },
        { entry: 'no' },
        { entry: 'maybe' }
        ]);

    function add(){
        items.push({entry: "new"})
    }

    return {
        items: items,
        add: add
    }
};

ko.applyBindings(vm);

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

person 4imble    schedule 28.04.2014