ForceModelCorrection
force model correction example
by Jaak Kütt
HTML
<script src="http://knockoutjs.com/downloads/knockout-2.3.0.debug.js"></script>
<script type="text/html" id="default">
<div class="item" data-bind="'if':id">
<div data-bind="html:content1"></div>
<div id="epos1" data-bind="contentAvailable: ['children','pos1']">
<div class="root" data-bind="template: { name: 'default', foreach: children().pos1 }">
</div>
<div>
<div id="epos2" data-bind="contentAvailable: ['children','pos2']">
<div class="root" data-bind="template: { name: 'default', foreach: children().pos2 }">
</div>
<div id="epos3" data-bind="contentAvailable: ['children','pos3']">
<span data-bind="html:children().pos3().length"></span>
<div data-bind="foreach: children().pos3()">
<span data-bind="html:id"></span>
</div>
</div>
</div>
</div>
</script>
<div class="root" data-bind="template: { name: 'default', foreach: items }">
</div>
CSS
.item{border:1px solid black;padding:10px;margin:10px;}
JavaScript
ko.bindingHandlers.contentAvailable = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
ko.utils.domData.set(element, '__ko_withIfBindingData', {});
return { controlsDescendantBindings: true };
},
'update': function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
console.log('fired update',element,valueAccessor());
var dataValue = ko.utils.unwrapObservable(valueAccessor());
if(!bindingContext.$data.hasOwnProperty(dataValue[0]) || typeof(bindingContext.$data[dataValue[0]]) != "function"){
bindingContext.$data[dataValue[0]]=ko.observable({});
}
if(!bindingContext.$data[dataValue[0]]().hasOwnProperty(dataValue[1]) || typeof(bindingContext.$data[dataValue[0]]()[dataValue(1)]) != "function"){
bindingContext.$data[dataValue[0]]()[dataValue[1]]=ko.observableArray([]);
shouldDisplay=true;
}else{
shouldDisplay=true;
}
var withIfData = ko.utils.domData.get(element, '__ko_withIfBindingData'),
isFirstRender = !withIfData.savedNodes,
needsRefresh = isFirstRender || (shouldDisplay !== withIfData.didDisplayOnLastUpdate);
if (needsRefresh) {
if (isFirstRender) {
withIfData.savedNodes = ko.utils.cloneNodes(ko.virtualElements.childNodes(element),true);
}
if (shouldDisplay) {
if (!isFirstRender) {
ko.virtualElements.setDomNodeChildren(element, ko.utils.cloneNodes(withIfData.savedNodes));
}
ko.applyBindingsToDescendants(bindingContext, element);
} else {
ko.virtualElements.emptyNode(element);
}
withIfData.didDisplayOnLastUpdate = shouldDisplay;
}
}
};
function viewChild(id){
...