contentAvailable

Check to see if content is available and create if not

by Jaak Kütt

HTML

<script src="http://knockoutjs.com/downloads/knockout-2.3.0.debug.js"></script>
<div class="root" data-bind="template: { name: 'default', foreach: items }">
    
</div>

<script type="text/html" id="default">
    <div class="item" data-bind="'if':id">
        <div data-bind="html:content"></div>
        <div data-bind="depend: ['children','pos1']">
            <div data-bind="template: { name: 'default', foreach: children().pos1 }"></div>
        </div>
        <div>
            <div data-bind="depend: ['children','pos2']">
                <div data-bind="template: { name: 'default', foreach: children().pos2 }"></div>
            </div>
            <div data-bind="depend: ['children','pos3']">
                <div data-bind="template: { name: 'default', foreach: children().pos3 }"></div>
            </div>            
        </div>
    </div>
</script>

CSS

.item{border:1px solid black;padding:10px;margin:10px;}

JavaScript

ko.bindingHandlers.depend = {     
    'update': function(e, vA, aBA, vM, bC) {
        var i = ko.utils.unwrapObservable(vA());
        if(!bC.$data.hasOwnProperty(i[0]) || typeof bC.$data[i[0]] !== 'function'){
            bC.$data[i[0]]=ko.observable({});
        }
        if(!bC.$data[i[0]]().hasOwnProperty(i[1]) || typeof bC.$data[i[0]]()[i[1]] !== 'function'){           
            var existing = bC.$data[i[0]]();
            existing[i[1]]=ko.observableArray([]);
            bC.$data[i[0]](existing);            
        }
    }    
};

function ViewChild(id){
    this.id=ko.observable(id);
    this.content=ko.observable('initial content for '+id);
    this.children=ko.observable({});
}
var child1=new ViewChild(1);
var child2=new ViewChild(2);
var child3=new ViewChild(3);
var child4=new ViewChild(4);
var child5=new ViewChild(5);

var MyViewModel={};
MyViewModel.items=ko.observableArray([]);

MyViewModel.items().push(child1);
ko.applyBindings(MyViewModel);

child1.children().pos1.push(child2);
child1.children().pos3.push(child3,child4);
child3.children().pos2.push(child5);