I discovered an issue using knockout bindings in HTML partials. I have a container region on a page. Its content is meant to be replaced dynamically dictated by my application's logic. I employ a detach/append technique to do it. However I noticed that updates are not propagated when element is detached. Not only that, in some cases bindings are lost altogether and when element is attached back, update stops working.
Updating data is important in my case because while an element may not be visible, it still could be updated asynchronously.
I found threads on the stackoverflow pointing to the same problem. However I couldn't find a definitive answer. There were various workarounds that didn't look appealing (e.g. using private knockout methods). The only way for me to make things work as intended is to show/hide partials instead of detach/append.
Is this behavior by design (I mean knockout library design)? If so, I wouldn't want to circumvent it by introducing various workarounds leading to potentially more problems down the road. If not, what is the recommended pattern of use for append/detach in knockout to make it work just like show/hide (I'd rather use detach/append because main application uses this policy for all of its containers).
Here's jsbin link to reproduce the problem. I also included show/ hide sample for comparison: http://jsbin.com/iTIrigAp/3/edit?html,js,output
<h3>Attach/Detach</h3>
<p>issue 1: Detach/Update/Attach/Update</p>
<p>issue 2: Run with JS/Update/Enter new val/Detach/Update/Attach</p>
<div id="attdet">
<input type="text" data-bind="value: a" />
<input type="text" data-bind="value: b" />
</div>
<button id="detach">Detach</button>
<button id="update">Update</button>
<button id="attach">Attach</button>
function ViewModel() {
this.a = ko.observable("a");
this.b = ko.observable("b");
this.c = ko.observable("c");
this.d = ko.observable("d");
}
var vm = new ViewModel();
ko.applyBindings(vm, document.getElementById("attdet"));
var nodes = null;
$("#detach").click(function () {
nodes = $("#attdet").children().detach();
});
$("#attach").click(function () {
$("#attdet").append(nodes);
});
$("#update").click(function () {
vm.a("att-det");
vm.b("att-det");
});