Reputation: 100220
Is there a good pattern for Backbone in order to distinguish change events that are a result from a server fetch versus change events that are due to the front-end events?
this.on('change',function(model){
self.needsPersisting = true;
});
For example: if the change is the result of the server, I don't wish to set the needsPersisting flag to true, but if the change is a result of the front-end I do wish to set the needsPersisting flag to true.
Upvotes: 0
Views: 92
Reputation: 11
There can be multiple solutions for this issue. You can pick your solution based on your requirement:
1. Distinguish based on variable name :
There is a parse function in Backbone (both model and collection have that function) which is called whenever the model/collection is returned by the server. We can override that function and set the variable before returning the response.
parse: function(response){
// Setting variable value
this.changedByServer = true;
// Returning response as this will be mapped to model/collection
return response;
}
2. Distinguish based on event
This approach is useful in cases where resetting model/collection after server fetch is acceptable. We can fetch the model with option "reset:true" and it will trigger "reset" event when the model gets fetched from server.
modelObj.fetch({reset: true});
modelObj.on('reset', function(){
// This handler is called when model gets fetched from server
});
Upvotes: 1
Reputation: 100220
If you look at the annotated source for Backbone, there is a fetch method for a model:
fetch: function(options) {
options = _.extend({parse: true}, options);
var model = this;
var success = options.success;
options.success = function(resp) {
var serverAttrs = options.parse ? model.parse(resp, options) : resp;
if (!model.set(serverAttrs, options)) return false;
if (success) success.call(options.context, model, resp, options);
model.trigger('sync', model, resp, options);
};
wrapError(this, options);
return this.sync('read', this, options);
},
from what I can tell, a 'sync' event is fired not only when this model is sync but also any collection that contains the model.
so the I way I seem to have solved it, is to deal with the fact that a 'change' event is fired when the server attributes are set, by knowing that the 'sync' event will fire afterwards, which will overwrite the boolean flag that I have for persisting a model, so this seems to work:
var BaseModel = Backbone.Model.extend({
needsPersisting: false,
constructor: function () {
var self = this;
this.on('change',function(model,something){
self.needsPersisting = true; //fired when attributes are changed, regardless over whether from server or client
});
this.on('sync',function(){
self.needsPersisting = false; //sync event is fired on fetch after the change event is fired in the source
});
Backbone.Model.apply(this, arguments);
}
});
Upvotes: 0