Reputation: 2802
We're using knockout for a SPA consisting of multiple view models, to handle what view be visible we have wrapped the divs where we bind the 'sub' view models in with bindings.
The problem we're seeing is that when a views visibility is toggled, the Custom bindings inside it are executed, both init & update, every time.
This causes a problem for us when we have a binding based on this jqdialog binding and on each init a new dialog is created and appended to our DOM but we have no simple way of knowing when it should be removed.
More or less it's a question about if we should rearrange this part of our arcitecture or if something is missing in our binding.
Simple view:
<div id="view">
<button data-bind="click: on">On</button>
<button data-bind="click: off">Off</button>
<div data-bind="with: visible">
<span data-bind="foo: ''">foo</span>
visible
</div>
</div>
Js:
ko.bindingHandlers.foo= {
init: function() {
alert("init");
},
update: function() {
alert("update");
}
}
var vm =(function() {
var self = this;
self.visible = ko.observable(false);
self.on = function() { self.visible(true); };
self.off= function() {self.visible(false); };
})();
ko.applyBindings(vm, document.getElementById("view"));
A small fiddle roughly showing our error.
Upvotes: 2
Views: 1706
Reputation: 45135
Your problem is that you are not toggling the visibility. When you use with
you are removing and reinserting the same elements into the DOM each time. This, of course, causes the binding to be recreated and the init
function to fire again.
If you just want to hide/show, use the visible binding instead.
So if you do this:
<div data-bind="visible: visible">
<span data-bind="foo: ''">foo</span>
visible
</div>
You'll see you binding initializes when the page loads and doesn't get initialized again as you show/hide. See here.
Upvotes: 2