Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how backbone.js model fetch method works

Tags:

i am very confuse about using backbone.js model fetch method. See the following example
backbone router:

profile: function(id) {   var model = new Account({id:id});   console.log("<---------profile router-------->");   this.changeView(new ProfileView({model:model}));   model.fetch(); }   

the first step, the model account will be instantiated, the account model looks like this.

define(['models/StatusCollection'], function(StatusCollection) {   var Account = Backbone.Model.extend({     urlRoot: '/accounts',      initialize: function() {       this.status       = new StatusCollection();       this.status.url   = '/accounts/' + this.id + '/status';       this.activity     = new StatusCollection();       this.activity.url = '/accounts/' + this.id + '/activity';     }   });    return Account; }); 

urlRoot property for what is it? After model object created, the profileview will be rendered with this this.changeView(new ProfileView({model:model}));, the changeview function looks like this.

changeView: function(view) {   if ( null != this.currentView ) {     this.currentView.undelegateEvents();   }   this.currentView = view;   this.currentView.render(); }, 

after render view, profile information will not display yet, but after model.fetch(); statement execute, data from model will be displayed, why? I really don't know how fetch works, i try to find out, but no chance.

like image 407
softshipper Avatar asked May 14 '13 13:05

softshipper


1 Answers

I'm not entirely sure what your question is here, but I will do my best to explain what I can.

The concept behind the urlRoot is that would be the base URL and child elements would be fetched below it with the id added to that urlRoot.

For example, the following code:

var Account = Backbone.Model.extend({     urlRoot: '/accounts' }); 

will set the base url. Then if you were to instantiate this and call fetch():

var anAccount = new Account({id: 'abcd1234'}); anAccount.fetch(); 

it would make the following request:

GET /accounts/abcd1234 

In your case there, you are setting the urlRoot and then explicitly setting a url so the urlRoot you provided would be ignored.

I encourage you to look into the Backbone source (it's surprisingly succinct) to see how the url is derived: http://backbonejs.org/docs/backbone.html#section-65

To answer your other question, the reason your profile information will not display immediately is that fetch() goes out to the network, goes to your server, and has to wait for a reply before it can be displayed.

This is not instant.

It is done in a non-blocking fashion, meaning it will make the request, continue on doing what it's doing, and when the request comes back from the server, it fires an event which Backbone uses to make sure anything else that had to be done, now that you have the model's data, is done.

I've put some comments in your snippet to explain what's going on here:

profile: function(id) {   // You are instantiating a model, giving it the id passed to it as an argument   var model = new Account({id:id});   console.log("<---------profile router-------->");    // You are instantiating a new view with a fresh model, but its data has    // not yet been fetched so the view will not display properly   this.changeView(new ProfileView({model:model}));    // You are fetching the data here. It will be a little while while the request goes   // from your browser, over the network, hits the server, gets the response. After   // getting the response, this will fire a 'sync' event which your view can use to   // re-render now that your model has its data.   model.fetch(); } 

So if you want to ensure your view is updated after the model has been fetched there are a few ways you can do that: (1) pass a success callback to model.fetch() (2) register a handler on your view watches for the 'sync' event, re-renders the view when it returns (3) put the code for instantiating your view in a success callback, that way the view won't be created until after the network request returns and your model has its data.

like image 50
Victor Quinn Avatar answered Oct 21 '22 12:10

Victor Quinn