What exactly happens when you save a Backbone model? - javascript

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

Related

backbone model get attribute within initialize method

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) {
// ...
}
});

How to bind server side events on client objects and vice versa with meteor

Is it possible to directly bind server side events to client side objects in meteor?
I would like to update a view for example when a server side event triggers. On the other hand I'd like to fire a server side method when a user clicks a view item.
I could use Meteor#methods for all the events but that seems odd.
Or can I specify an eventhandler for example using EventEmitter outside the client- and server-scope so that it is available on both sides and trigger/bind events ob that very object?
Some confused about that I am thankful for hints into the right direction.
Regards
Felix
Update:
Using Meteor#methods works great in case user events should be mapped to server side actions. The other way around is still unclear. Asynchronous actions on serverside could persist their results in a collection which is pub/sub'ed to the client, which in turn could update some view due to the reactive context. But thats odd, cause persisting that kind of info is slow, wasted space and time. Any suggestions?
I believe you can use the Collection.observe on the server side to 'observe' events on the Collection as clients are inserting, updating, removing, etc... That might be a start if you are focused on Collections alone. I used it like a sort of server side event loop to watch for collection changes.
When a user clicks on something in a view try binding a Template Event to the View css selector and then calling a Meteor method which will notify the server of the event. See the examples of binding a key handler and/or button handlers to a Template.entry.event which then call a Meteor method notifying the server that something happened.
What about storing the progress in Session? You could do something like this:
Template.progress.value = function() {
return Session.get('progress');
}
Then, whenever you update the Session on the server, the client template will automatically get those changes.
Out of curiosity, how exactly are you performing asynchronous actions on the server? I'm still trying to figure that out.

Are both the 'sync' event and Backbone.sync connected in some way -- what is the difference between the two?

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.

Are there any Backbone.js tutorials that teach ".sync" with the server?

I read many Backbone.js tutorials, but most of them deal with static objects.
Of course, I have data on the server. I want a tutorial that shows how backbone.js can communicate with the server to fetch data, post data, etc.
This is .sync, right? I read the backbone.js documentation, but still fuzzy on how to use this feature.
Or can someone show me an example?
According to: http://documentcloud.github.com/backbone/#Sync
Backbone.sync is the function that Backbone calls every time it
attempts to read or save a model to the server.
But when? Where do I put the function? I don't know how to use it, and the documentation doesn't give any examples. When does the data get loaded into my models? I get to define when...right?
You never really have to look at .sync, unless you plan to overwrite it. For normal uses, you can simply call model.save() whenever you want and that will execute a post or put (depending on whether the record exists already). If you want to get the data from your backend, use collection.fetch()
You'll of course also need to specify a URL, do so through your collection attribute, collection.url
You can override Backbones native sync functionality if you override it:
Backbone.sync = function() {
//Your custom impl here
}
After that this function is called whenever you call a backbone function like .save() on models or .fetch() on collections. You do not have to care about data transport anymore.
I would suggest taking a look into Backbones source and look how the default sync function is implemented. Then create your own or adopt your server to support the native function.
They are not free, but the following screencasts both have a piece on backend work and how to send data to and get data from Backbone.
Tekpub is a 9 part screencast about asp.net MVC3, with the whole 6th part about using backbone to write an admin module to manage productions. it shows all about handling routing in MVC3 and sending & receiving data
Peepcode
http://peepcode.com/products/backbone-js about basic backbone stuff
http://peepcode.com/products/backbone-ii about interactivity
http://peepcode.com/products/backbone-iii about persistance (it's this third one you will need for server connection information).

BackboneJS, create and destroy, but no update method?

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.

Categories

Resources