Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting change to Knockout view model

Sure this is a very easy question to answer but is there an easy way to determine if any property of a knockout view model has changed?

like image 557
user1389723 Avatar asked May 16 '12 16:05

user1389723


People also ask

How do we activate a Knockout model?

To activate Knockout, add the following line to a <script> block: ko. applyBindings(myViewModel); You can either put the script block at the bottom of your HTML document, or you can put it at the top and wrap the contents in a DOM-ready handler such as jQuery's $ function.

How do I assign a value to Knockout observable?

To create an observable, assign the ko. observable function to the variable. A default value can be specified in the constructor of the call. Knockout then converts your variable into a function and tracks when the value changes, in order to notify the UI elements associated with the variable.

Which function is used to perform Knockout computation?

Determining if a property is a computed observable Knockout provides a utility function, ko.

What is observable in Knockout?

Knockout. js defines an important role when we want to detect and respond to changes on one object, we uses the observable. An observable is useful in various scenarios where we are displaying or editing multiple values and require repeated sections of the UI to appear and disappear as items are inserted and deleted.


2 Answers

Use extenders:

ko.extenders.trackChange = function (target, track) {     if (track) {         target.isDirty = ko.observable(false);         target.originalValue = target();         target.setOriginalValue = function(startingValue) {             target.originalValue = startingValue;          };         target.subscribe(function (newValue) {             // use != not !== so numbers will equate naturally             target.isDirty(newValue != target.originalValue);         });     }     return target; }; 

Then:

self.MyProperty= ko.observable("Property Value").extend({ trackChange: true }); 

Now you can inspect like this:

self.MyProperty.isDirty() 

You can also write some generic viewModel traversing to see if anything's changed:

self.isDirty = ko.computed(function () {     for (key in self) {         if (self.hasOwnProperty(key) && ko.isObservable(self[key]) && typeof self[key].isDirty === 'function' && self[key].isDirty()) {             return true;         }     } }); 

... and then just check at the viewModel level

self.isDirty() 
like image 101
Brett Green Avatar answered Oct 17 '22 08:10

Brett Green


You can subscribe to the properties that you want to monitor:

myViewModel.personName.subscribe(function(newValue) {     alert("The person's new name is " + newValue);  }); 

This will alert when personName changes.

Ok, so you want to know when anything changes in your model...

var viewModel = … // define your viewModel  var changeLog = new Array();    function catchChanges(property, value){     changeLog.push({property: property, value: value});     viewModel.isDirty = true; }  function initialiseViewModel() {     // loop through all the properties in the model     for (var property in viewModel) {          if (viewModel.hasOwnProperty(property)) {               // if they're observable             if(viewModel[property].subscribe){                  // subscribe to changes                 viewModel[property].subscribe(function(value) {                     catchChanges(property, value);                 });             }         }     }     viewModel.isDirty = false; }  function resetViewModel() {     changeLog = new Array();       viewModel.isDirty = false; } 

(haven't tested it - but you should get the idea)

like image 22
web_bod Avatar answered Oct 17 '22 10:10

web_bod