Model's save method by default triggers sync event after the server has acknowledged the change. Is there any way to silence that sync event on model's save?
You can look at the portion of the save method that calls sync in the annotated source:
model.trigger('sync', model, resp, options);
It’s pretty deep in there. You could override the save method to remove that line.
Why do you want to do this?
Related
I fetch data from the server and want to change some string with I18n strings before the subscribers are notified of the model change. Is there a way to add a success method that will always called in first place after fetching data?
Ok found by myself.
Model.parse
http://backbonejs.org/docs/backbone.html#section-65
I've looked for a solution to this but cannot find anything that works.
Note: I am overriding the Backbone.sync method globally.
When I instantiate a Session model I pass a number of attributes to it. These, as you would expect, should be "gettable" via mySessionInstance.get('someAttribute'). The session model calls this.fetch() within the initialize method. My custom Backbone.sync method needs to access some of the session attributes but when it runs I get an error saying the "get" method does not exist for that instance.
It's as if I was trying to access .get for my session instance before it was fully initialized. Any ideas on how to fix it? I wish there was a "ready" or "initialized" event for models so I could just listen for that and ensure certain things only happen when the model is truly done initializing.
Thanks,
Luis
There are two events that a model fetch will trigger:
"change" events will be triggered if anything is changed (i.e. if anything came back from the server). A fetch is mostly a set that is called by an AJAX success handler after all.
A "sync" event will be triggered when the model is synced with the server, syncing includes fetching. The fetch docs aren't explicit on this but you can easily see it in the source and the master events list notes it.
The "change" event is probably more useful in general and should serve to indicate that the model is ready for use.
If you just need a one-time notification, you could use use the success callback from the fetch:
model.fetch({
success: function(model, response) {
// ...
}
});
What exactly happens when you save a Backbone model? Here's the best I can piece together by reading the documentation here:
model.save([attributes], [options]) is called
A "change" event is fired (but only if the attributes are new)
The server is notified of the change?
A "sync" event is called once the server returns
But I'm a Backbone noob and I'm sure someone else could do a way better job of explaining.
I'm partly just curious what happens. I'm also having trouble understanding how Backbone comes up with the JSON object it sends to the server. I'm having a separate problem where the JSON object is not what I want it to be, but I don't know how to change it.
The detailed process can be found in the annotated source code for Backbone.Model.save and Backbone.sync.
If you ignore options.wait and options.silent, your decomposition is mostly correct.
When you issue a model.save:
the attributes passed to the function are set, a change event is fired if the values changed
save delegates the request to model.sync or Backbone.sync
sync serializes the data to a JSON string by calling JSON.stringify(model.toJSON())
An Ajax request is sent to sent to server, a POST request for a new object, a PUT for an update. The target URL is defined by model.url (or collection.url/id)
When the request completes, the model is updated with the server response, if any, and triggers a change event accordingly.
Success or error callbacks are called, a sync event is triggered if no success callback is defined.
Usually, you can customize this behaviour by overriding model.toJSON or model.sync
first,I suggest you read the source code of the backbone, is really very simple.Default backbone and server-side interaction is achieved through backbone.sync.
second,You can trace debug model.save method of code again, naturally know the details.
I suggest you start here:
http://backbonejs.org/examples/todos/index.html
What is the difference between 'sync' event and Backbone.sync?
...and what are they each specifically?
There is no connection between the two, although they are both related to the task of syncing data to the server.
Backbone.sync implements the persistence strategy utilized by your Backbone.js app. If you need to change something about the way your data is stored, you are welcome to override the default implementation. Most people won't need to worry about this, but if you need to do this you might want to check out How to override Backbone.sync?
The sync event indicates an update to a model has been successfully synchronized with the server. Like other model events, it will bubble up to the collection as well. This happens when:
Successfully saving a model.
Successfully destroying a model.
Successfully creating a model in a collection.
Note: Prior to v0.9.9, the sync event was not guaranteed to fire - if you declared a success callback during any one of these operations, the sync event would not be triggered.
I noticed that in BacbkoneJS there is a method in the Collection object that allows you to add a new model to that collection, while at the same time pushing the new model to the Server. This is convenient because it will only add the new model to the collection if the ajax request is successful. It will also update the ID on the model with the one returned from the server.
There is also a similar method on the Model object called destroy, this will only destroy the model if the ajax request returns 200.
How can I achieve something similar to this with Update, where when I set data on my model, it will attempt to save the model to the server, ensure a 200 status, and then fire the "change" event?
The problem is If I set the model data (I have to do this in order to call save()), then the change event fires.
Thanks
The Backbone.Model.save() method allows you to specify the properties you want to change. Looking at the annotated source code, it looks like the "model.set()" happens on a successful response from the server.
So, instead of doing
myModel.set({this:"that"});
myModel.save();
Do
myModel.save({this:"that"});
and the change event should fire after a successful save.
Note: I have not tested this - this is just from reading the source.