I\'ve just upgraded to 2.3.0 and now I\'m getting the error
You cannot apply bindings multiple times to the same element.
that
ko.cleanNode($("#modalPartialView")[0]);
ko.applyBindings(vm, $("#modalPartialView")[0]);
works for me, but as others note, the cleanNode
is internal ko
function, so there is probably a better way.
Now that we can use dataFor()
to check if the binding has been applied, I would prefer check the data binding, rather than cleanNode()
and applyBindings()
.
Like this:
var koNode = document.getElementById('formEdit');
var hasDataBinding = !!ko.dataFor(koNode);
console.log('has data binding', hasDataBinding);
if (!hasDataBinding) { ko.applyBindings(vm, koNode);}
A lot of answers already!
First, let's say it is fairly common that we need to do the binding multiple times in a page. Say, I have a form inside the Bootstrap modal, which will be loaded again and again. Many of the form input have two-way binding.
I usually take the easy route: clearing the binding every time before the the binding.
var koNode = document.getElementById('formEdit');
ko.cleanNode(koNode);
ko.applyBindings(vm, koNode);
Just make sure here koNode
is required, for, ko.cleanNode()
requires a node element, even though we can omit it in ko.applyBinding(vm)
.
You should never apply bindings more than once to a view. In 2.2, the behaviour was undefined, but still unsupported. In 2.3, it now correctly shows an error. When using knockout, the goal is to apply bindings once to your view(s) on the page, then use changes to observables on your viewmodel to change the appearance and behaviour of your view(s) on your page.
Something that can happen as well which throws this exception is the following. Say you have:
ko.applyBindings(myViewModel1, document.getElementById('element1'));
...
ko.applyBindings(myViewModel2, document.getElementById('element2'));
Now, when both #element1 and #element2 don't exist you'll get the error. The reason is that Knockout's applyBindings falls back on document.body as root element when #element1 and #element2 are not found. Now it tries to apply binding twice on the body...
Not a nice fallback of Knockout if you ask me. I'd rather have a clear error message that the element does not exist in the DOM (yet).
Hope this helps some people.
Two things are important for above solutions to work:
When applying bindings, you need to specify scope (element) !!
When clearing bindings, you must specify exactly same element used for scope.
Code is below
Markup
<div id="elt1" data-bind="with: data">
<input type="text" data-bind="value: text1" >
</form>
Binding view
var myViewModel = {
"data" : {
"text1" : "bla bla"
}
}:
Javascript
ko.applyBindings(myViewModel, document.getElementById('elt1'));
Clear bindings
ko.cleanNode(document.getElementById('elt1'));
There are a lot of great answers for this issue but I have a noobie answer.
I found that I accidentally added the same Script in two places and it was trying to bind twice. So before you pull your hair out on a simple mistake, make sure you check for this issue.