Knockout: "You cannot apply bindings multiple times to the same element" during traversing a DOM tree after applyBindings

Created on 29 Jul 2013  路  7Comments  路  Source: knockout/knockout

I have 褋ustom binding handler 'overlay', which moves content into another container during the processing (see http://jsfiddle.net/San4es/ESCT4/). After calling ko.applyBindings, I get the exception: "You cannot apply bindings multiple times to the same element". I understand that the problem is related to a modification of the DOM tree during traversing by Knockout.

How can I avoid this issue? Is the problem the expected?

Thanks,
Alexander.

All 7 comments

Try to call ko.cleanNode(domNode) before ko.applyBindings

So in fact if I call cleanNode then all subscriptions will be disposed contrary to the desired result.

But you get this exception just because you call applyBindings multiple times; each time when you call this method subscriptions will be recreated. So, I believe this approach should work:

ko.cleanNode(element);
ko.applyBindgings(viewModel, element);

Unfortunately, the scenario you are talking about is not my case. I don't call applyBindings several times. In my case, it is called exactly once. The problem is that the Knockout recursively traverses DOM tree, and when it encounters a node, which is processed in the same call stack, error is triggered.
This is due to the fact that knockout traverses the DOM tree by "depth-first" and when I move the processed element up the DOM hierarchy knockout meets this element once again.

Probably you can fix this by returning { controlsDescendantBindings: true } from your binding handler's init function. See http://knockoutjs.com/documentation/custom-bindings-controlling-descendant-bindings.html

Oh, I understood the problem. Do you really need to move existing element somewhere else? It's a little bit strange behavior. Looks like some type of hacks. You creates instance of anonymous template engine just because you want to call nodes method. And then you call renderTemplate which also creates anonymous template object... Anyway even your solution can be fixed using one more custom binding stopBinding. You can check working example: http://jsfiddle.net/ESCT4/12/ .
Anyway I recommend to reconsider this solution it looks too complicated (I even don't understand what you want to achieve using this overlay binding. Looks like you put part of ViewModel responsibilities into View) but up to you

I'll close this as it's by design (and so old that it's unlikely still to be an active concern). Please reopen if anyone disagrees!

Was this page helpful?
0 / 5 - 0 ratings