Reputation: 2788
I'm looking for unbind functionality in knockout. Unfortunately googling and looking through questions asked here didn't give me any useful information on the topic.
I will provide an example to illustrate what kind of functionality is required.
Lets say i have a form with several inputs. Also i have a view model binded to this form. For some reason as a reaction on user action i need to unbind my view model from the form, i.e. since the action is done i want all my observables to stop reacting on changes of corresponding values and vise versa - any changes done to observables shouldn't affect values of inputs.
What is the best way to achieve this?
Upvotes: 41
Views: 22965
Reputation: 96
<html>
<head>
<script type="text/javascript" src="jquery-1.11.3.js"></script>
<script type="text/javascript" src="knockout-2.2.1.js"></script>
<script type="text/javascript" src="knockout-2.2.1.debug.js"></script>
<script type="text/javascript" src="clickHandler.js"></script>
</head>
<body>
<div class="modelBody">
<div class = 'modelData'>
<span class="nameField" data-bind="text: name"></span>
<span class="idField" data-bind="text: id"></span>
<span class="lengthField" data-bind="text: length"></span>
</div>
<button type='button' class="modelData1" data-bind="click:showModelData.bind($data, 'model1')">show Model Data1</button>
<button type='button' class="modelData2" data-bind="click:showModelData.bind($data, 'model2')">show Model Data2</button>
<button type='button' class="modelData3" data-bind="click:showModelData.bind($data, 'model3')">show Model Data3</button>
</div>
</body>
</html>
@Mark Robinson gave perfect solution, I've similar problem with single dom element and updating different view models on this single dom element.
Each view model has a click event, when click happened everytime click method of each view model is getting called which resulted in unnecessary code blocks execution during click event.
I followed @Mark Robinson approach to clean the Node before apply my actual bindings, it really worked well. Thanks Robin. My sample code goes like this.
function viewModel(name, id, length){
var self = this;
self.name = name;
self.id = id;
self.length = length;
}
viewModel.prototype = {
showModelData: function(data){
console.log('selected model is ' + data);
if(data=='model1'){
ko.cleanNode(button1[0]);
ko.applyBindings(viewModel1, button1[0]);
console.log(viewModel1);
}
else if(data=='model2'){
ko.cleanNode(button1[0]);
ko.applyBindings(viewModel3, button1[0]);
console.log(viewModel2);
}
else if(data=='model3'){
ko.cleanNode(button1[0]);
ko.applyBindings(viewModel3, button1[0]);
console.log(viewModel3);
}
}
}
$(document).ready(function(){
button1 = $(".modelBody");
viewModel1 = new viewModel('TextField', '111', 32);
viewModel2 = new viewModel('FloatField', '222', 64);
viewModel3 = new viewModel('LongIntField', '333', 108);
ko.applyBindings(viewModel1, button1[0]);
});
Upvotes: 1
Reputation: 13278
You can use ko.cleanNode
to remove the bindings. You can apply this to specific DOM elements or higher level DOM containers (eg. the entire form).
See http://jsfiddle.net/KRyXR/157/ for an example.
Upvotes: 50
Reputation: 3039
@Mark Robinson answer is correct.
Nevertheless, using Mark answer I did the following, which you may find useful.
// get the DOM element
var element = $('div.searchRestults')[0];
//call clean node, kind of unbind
ko.cleanNode(element);
//apply the binding again
ko.applyBindings(searchResultViewModel, element);
Upvotes: 16