2013-01-14 javascript knockoutjs
Иногда шаблоны для клиентских приложений хранятся на сервере и передаются клиенту в момент когда knockout.js уже работает (после вызова ko.applyBindings), при этом биндинг "html" выведет шаблон как есть, что-бы привязывание сработало внутри шаблона можно использовать биндинг htmlbind.
Сам биндинг с комметариями:
// Размещаем новый биндинг
ko.bindingHandlers['htmlbind'] = {
// При инициализации
'init': function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
// Управление внудренними привязками самостоятельно
return { 'controlsDescendantBindings': true };
},
// При изменении значения переменой
'update': function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
// Получаем значение переменной
var dataValue = ko.utils.unwrapObservable(valueAccessor());
if(dataValue) {
// Переводим HTML строку в DOM элементы
var dom = document.createElement('div');
dom.innerHTML = dataValue;
var nodes = ko.utils.arrayMap(dom.childNodes, function(d){ return d })
// Устанавливаем DOM в документ
ko.virtualElements.setDomNodeChildren(element, nodes);
// Передаем контекст, модель, переменные
ko.applyBindingsToDescendants(bindingContext, element);
} else {
// Очищаем DOM когда переменная пустая
ko.virtualElements.emptyNode(element);
}
}
};
ko.expressionRewriting.bindingRewriteValidators['htmlbind'] = false;
// Возможность использовать как виртуальный элемент
ko.virtualElements.allowedBindings['htmlbind'] = true;