I have created a KnockoutJS application, and I also must use some third-party stuff with it. My third-party stuff uses vanilla Javascript to insert a div into the markup rendered by Knockout. Once this happens, Knockout stops working.
Here's a fiddle that encapsulates the problem: http://jsfiddle.net/p5o8842w/1/
HTML:
<div style="margin-bottom:50px;">
<button onclick='BindVM();' >Bind</button>
<button onclick='ThrowWrench();'>Throw a Wrench Into It</button>
</div>
<div id="ViewModel" data-bind="template: 'Template'">
</div>
<script type="text/html" id='Template'>
<div style="margin-bottom:20px;">
<span data-bind="text: Name"></span>
</div>
<div id="infoDiv">
<input type="text" data-bind="text: Name, value: Name, valueUpdate: 'keyup'" />
</div>
</script>
JavaScript:
function BasicVM () {
var self = this;
self.Name = ko.observable('The Name');
self.Title = ko.observable('The Title');
}
function BindVM() {
var vm = new BasicVM();
var element = document.getElementById('ViewModel');
ko.cleanNode(element);
ko.applyBindings(vm, element);
}
function ThrowWrench() {
var element = document.getElementById('infoDiv');
element.innerHTML = "<div class='container'>" + element.innerHTML + '</div>';
}
First, click 'Bind.' Notice that the textbox is bound to the span; change the box, you change the span.
Then, click 'Throw a Wrench Into It.' Now, the textbox is no longer data-bound to the ViewModel, and typing into it doesn't impact the span.
Things I can't do:
- Take the third-party code and refactor/integrate it into my Knockout stuff.
- Run the third-party code before I render with Knockout (which I think would help).
- Call ko.applyBindings again after running the third-party code. I can do this, but then Knockout destroys what the third-party code did, so I'd have to run it again, which would cause the same problem again.
Is there any way around this?