I am trying to understand some slightly odd behavior I am seeing in a page I am making using KnockoutJS. An observable array seems to get duplicate items every time I clear and reapply bindings. The quickest way to understand the problem is to look at this JSFiddle demo. Just click any edit button several times, and watch this list grow!
The heart of the code for this demo is in the following method:
var _bindItemDetail = function (jsonData) {
//clear existing bindings
ko.cleanNode($("#itemdetails").get(0));
// observables in selected item.
_viewModel.SelectedItem(ko.mapping.fromJS(jsonData));
// Apply Bindings
ko.applyBindings(_viewModel.SelectedItem, $("#itemdetails").get(0));
};
The essence of what I am trying to achieve is to create a list and details page in one. The list JSON is fetch on initial page load, and the detail JSON is fetched and bound to the “detail” html whenever an edit link is clicked.
In addition to solving the problem, I am trying to understand the behavior, and learn some lessons about how to clean up stale resources properly when using knockout.
Thanks for any help
The problem is that in your
_bindItemDetailfunction, you are reapplying the bindings on your modified view where you already had replicated the elements.ko.cleanNode()merely removes bindings from the elements, it doesn’t revert the view back to its initial state. In general, you should only ever callko.applyBindingson a set of nodes once. Doing it more than once, is just asking for problems.Frankly you’re not really making good use of knockout. The majority of your code is using jquery to handle all the low-level details. The point of using knockout is to not have to worry about those lower level details.
I’ve adjusted your fiddle a bit to make better use of knockout with less emphasis on using jquery.
In the view:
clickbinding to handle yourEditclick events.withbinding to conditionally show the editor fields. ThestopBindingshandler is not needed.In the view model:
editClickedto the view model.ko.cleanNode/ko.applyBindingscombo you had when binding items. You shouldn’t do that and you just don’t need it, knockout will handle all that for you.Updated fiddle