KO lazy template load test
by whelkaholism
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<a data-bind="click: load1">load1</a> |
<a data-bind="click: load2">load2</a> |
<a data-bind="click: load3">load no template</a>
<hr/>
<b>Explicit model</b>
<div data-bind="lazy: { model: ReportData, template: ReportTemplate }">
</div>
<hr/>
<b>Implicit model</b>
<!-- ko with: ReportData -->
<div data-bind="lazy: $parent.ReportTemplate"></div>
<!-- /ko -->
JavaScript
ko.bindingHandlers.lazy = {
init:
function(el, f_valueaccessor, allbindings, viewmodel, bindingcontext)
{
return { controlsDescendantBindings: true }
},
update:
function(el, f_valueaccessor, allbindings, viewmodel, bindingcontext)
{
// Get current value of supplied value
var field = f_valueaccessor();
var o = ko.unwrap(field);
var model, template, options = {};
if(o.model)
{
model = ko.unwrap(o.model);
template = ko.unwrap(o.template);
options = o.options || options;
}
else
{
model = ko.unwrap(bindingcontext.$data);
template = o;
}
var ctx = bindingcontext;
ctx = bindingcontext.createChildContext(model);
$(el).empty();
if(model && template)
{
var els = $(template).appendTo(el);
console.log(['update', o.model ? 'explicit' : 'implicit', model, template, els]);
ko.applyBindingsToDescendants(ctx, el);
}
}
};
function ReportDataModel()
{
this.Items = ko.observableArray([
{ ID:1, Label:'Widgets', Amount:'£10000.00' },
{ ID:2, Label:'Wodgets', Amount:'£20000.00' },
{ ID:3, Label:'Gadgets', Amount:'£50000.00' },
{ ID:4, Label:'Gidgets', Amount:'£15400.00' },
{ ID:5, Label:'Bodgets', Amount:'£10345.00' },
{ ID:6, Label:'Badgets', Amount:'£23000.00' },
{ ID:7, Label:'Badgers', Amount:'£44000.00' },
{ ID:8, Label:'Bodgers', Amount:'£10555.00' }
]);
}
function Model()
{
this.ReportData = ko.observable();
this.ReportTemplate = ko.observable();
this.load1 = function()
{
this.ReportTemplate(
'<ul data-bind="foreach: Items"><li>' +
'<b data-bind="text: ID"></b>' +
'<span data-bind="text: Label"></span>' +
'<span data-bind="text: Amount"></span>' +
'</li></ul>'
);
this.ReportData(new ReportDataModel());
};
...