Using KnockoutJS with detached nodes

2019-01-28 07:15发布

问题:

What I'm looking to do is detach some nodes using jQuery's detach method, update my ViewModel, attach my nodes back, and have the values be updated.

Is this possible?

Here's a full fiddle of what I'm shooting for. Basically, I'd like to be able to go from left to right, click detach, update, and attach and have fresh values in the textboxes.


UPDATE

Based on RP's answer, the best bet, assuming this fits your use case, is to attach them to the dom hidden, update your viewmodel, and then show your nodes. Something like this works for me:

$("#updateAndAttach").click(function () {
    var junk = $("<div />").css("display", "none");
    junk.append(nodes);
    $("#home").append(junk);

    vm.a("AAA");
    vm.b("BBB");

    $(nodes).unwrap();
});

END UPDATE


Here's the full code:

JavaScript

$(function () {

    function ViewModel() {
        this.a = ko.observable("a");
        this.b = ko.observable("b");
    }

    var vm = new ViewModel();

    ko.applyBindings(vm, document.getElementById("home"));

    var nodes = null;

    $("#detach").click(function () {
        nodes = $("#home").children().detach();
    });

    $("#attach").click(function () {
        $("#home").append(nodes);
    });

    $("#update").click(function () {
        vm.a("AAA");
        vm.b("BBB");
    });
})();

HTML:

<div id="home">
    <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>

回答1:

The evaluation of the bindings in a single data-bind are wrapped in a computed observable that will dispose of itself when it is re-evaluated and recognizes that it is not part of the current document.

So, there is not a simple workaround that would allow you to do what you are trying. You could certainly hide the elements while updates are being made and then unhide them.



回答2:

What happens here is when you call detach method, ko loses bindings to detached nodes. The easiest way to make it work is to re-apply bindings each time you detach and attach nodes.

See this jsfiddle: http://jsfiddle.net/EZFDt/

Edit: With that workaround in place, keep in mind there may be performance implications. Perhaps you can re-think the way you approach the problem - can you move nodes to a different, hidden location instead of detaching them? Can you simply hide them?



回答3:

It's a while since you asked the question, but I have found using detach, then immediately append to some valid location in the DOM keeps all bindings working nicely. You may then detach, append to wherever you need it as your application changes state.

I use it for sections with multiple events attached, like JQUI elements, forms and the like so that I can keep one copy running around, and just append to the page I go to. eg. a Signup form, which also functions as Edit Profile.

In your case, initially appending it into a 'visibility:hidden;' node at some point that was clearly for detached elements could be reasonable.

Don Have a great day