var AppModel = Backbone.Model.extend({ // Model instance members go here ... defaults: { //Default model attributes }, initialize: function() { // This line will watch for changes in model object and will call the callback // i.e. The killer famous line! this.listenTo(this, "change", callback); } });
Whenever the model in your backbone application changes you can handle the "change" event in a pretty neat way like this:
object.listenTo(other, event, callback)
As you see the model.listenTo has three arguments: First is the model object, second is the type of event to be captured and finally the callback function which will be fired in case that event will happen.
So the idea here is to implement the same model.listenTo "change" method on the object literal or the model. I started looking at different stackoverflow discussions and finally made my decision. The solution (well, at least one of best ones to be fair) exists in a well-written library called Watch.JS. The weird thing about this case is that browser have different approaches regarding this. For example there is a sweat property on the Object prototype called Watch. I guess the idea behind Watch.JS is actually coming from there.
The steps needs to be taken are quite simple. First, add the source of Watch.js, Second create an object literal and third, enable watch for the object/array and attach a callback function to it, like the following chunk of code:
var defaultModelAttributes = { personName: "Amir Rahnama" }; //defining a 'watcher' for an attribute of your object literal / array watch(defaultModelAttributes, "personName", function() { alert("personName value changed!"); }); //when changing the attribute its watcher will be invoked defaultModelAttributes.personName = "A stupid guy";
You can also look for all changes in the same object literal by changing line 11 with the followings:
watch(defaultModelAttributes, function() { ... });
You can also set how deep you would like your changes to be watched, just pass in a depth token to the watch function after you declare the callback function, as in the following:
var defaultModelAttributes = { person: { personId: "870718-5768", personName: { firstName: "Amir", lastName: "Rahnama" } } }; watch(defaultModelAttributes, function(){ alert("defaultModelAttributes is changed"); }, 2); defaultModelAttributes.person.personName.lastName = "Akhavan";
UPDATE: I tried to use the library with RequireJS, but I believe that there should be a compatibility issues, there. I do not know the reason yet, but in case you are interested here is the link to issue on WatchJS Github page: Setting an object literal attribute with RequireJS does not trigger the passed callback function.
This comment has been removed by the author.
ReplyDeleteThank you very much for this useful article. I like it. security guard sihanoukville
ReplyDelete