17

With below code, input#p_in will be updated with the change of input#s_in. But I have used cleanNode(sec). Could anyone help understand why the binding is not cleared.

    <input id="p_in" data-bind="value: name"></input>
    <input id="s_in" data-bind="value: name"></input>
    <input id="cb" type="checkbox">same</input>

    <script type="text/javascript">
        function AddrDataSet (name) {
            this.name = ko.observable(name);
        };

        var primary_set = new AddrDataSet('p');
        var sec_set = new AddrDataSet('s');
        var pri = $('#p_in')[0];
        var sec = $('#s_in')[0];

        ko.applyBindings(primary_set, pri);
        ko.applyBindings(sec_set, sec);

        ko.cleanNode(sec); // clean it
        ko.applyBindings(primary_set, sec); // bind it to primary_set
        ko.cleanNode(sec); // clean it again

    </script>
rxing
  • 363
  • 1
  • 2
  • 7

1 Answers1

31

ko.cleanNode is used internally by Knockout to clean up data/computeds that it created related to the element. It does not remove any event handlers added by bindings or necessarily understand if a binding made changes to the DOM. This can definitely cause problems like having multiple handlers attached to an element when it is subsequently bound again.

So, I would not recommend using this pattern. A better pattern is to use with or the template binding around a section and allow it to be re-rendered with the new bindings.

RP Niemeyer
  • 114,592
  • 18
  • 291
  • 211
  • cleanNode is really an internal API. There is not currently docs on it specifically. – RP Niemeyer Feb 28 '13 at 13:01
  • 25
    @RPNiemeyer could you elaborate how "with" keyword could solve this problem? I'm in a similar situation, and a sub-modal window is opened/closed and i need to avoid calling apply bindings multiple times.. – Sonic Soul Apr 08 '14 at 20:04
  • 1
    The one legitimate use case I've found is when testing bindings or components. My afterEach function cleans out the element containing the test setup for the binding, then runs cleanNode on it to make KO forget it. Then I can start the next beforeEach, setting up the binding for test again. This way I have fully encapsulated tests. – Gert Sønderby Nov 26 '15 at 15:18
  • 2
    Same case as @SonicSoul – Csaba Toth Jan 19 '16 at 06:26
  • Wow, this helped me fix a problem I was fighting for almost a day non stop... http://stackoverflow.com/q/40291746/782719 – GETah Oct 27 '16 at 21:11