jquery ui - Knockout and JQueryUI binding does not call update callback -
when creating foreach binding custom one, "update:" callback not being called when pushing new element view model. however, new span(not accordion) item creating.
<div data-bind="foreach:items, koaccordion: {}"> <div> <span data-bind="text: id"></span> </div> <div> <span data-bind="text: name"></span> </div> </div>
the script:
ko.bindinghandlers.koaccordion = { init:function(element, valueaccessor, allbindingsaccessor, viewmodel,bindingcontext) { console.log("initialization callback"); $(element).accordion(); }, update:function(element, valueaccessor, allbindingsaccessor, viewmodel, bindingcontext) { console.log("updating callback"); $(element).accordion('destroy').accordion(); } }; function item(id,name,description){ this.id = ko.observable(id); this.name = ko.observable(name); this.description = ko.observable(description); } var viewmodel = { items:ko.observablearray([new item("new id","new name","new description")]), additem:function(id,name,description){ viewmodel.items.push(new item(id,name,description)) } }; ko.applybindings(viewmodel);
a binding's update()
function called when dependencies change.
that means must trigger knockout's dependency tracking inside body of update()
. happens producing underlying value of observable (in other words, calling it).
normally use value inside function, in case need step dependency tracking notices there subscriber.
this work:
<!-- pass observable here --> <div data-bind="foreach: items, koaccordion: items"> <div> <span data-bind="text: id"></span> </div> <div> <span data-bind="text: name"></span> </div> </div>
and
ko.bindinghandlers.koaccordion = { init: function (element, valueaccessor) { $(element).accordion(); // destroy widget when element gets removed ko.utils.domnodedisposal.adddisposecallback(element, function() { $(element).accordion('destroy'); }); }, update: function (element, valueaccessor) { // unwrap observable: registers implicit subscription ko.unwrap(valueaccessor()); $(element).accordion('refresh'); } };
but in essence can skip update
callback entirely , use explicit subscription instead:
ko.bindinghandlers.koaccordion = { init: function (element, valueaccessor) { var items = valueaccessor(), subscription; $(element).accordion(); // set explicit subscription subscription = items.subscribe(function () { $(element).accordion('refresh'); }); // destroy widget when element gets removed ko.utils.domnodedisposal.adddisposecallback(element, function() { subscription.dispose(); $(element).accordion('destroy'); }); } };
that being said, there mature jqueryui custom binding library should use, instead of rolling own: http://gvas.github.io/knockout-jqueryui/
Comments
Post a Comment