21

我对使用backbone.js 模型获取方法感到非常困惑。请参阅以下示例
骨干路由器:

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

第一步,模型账户会被实例化,账户模型是这样的。

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 属性是什么呢?创建模型对象后,profileview 将使用this.changeView(new ProfileView({model:model})); ,changeview函数看起来像这样。

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

在渲染视图之后,配置文件信息还不会显示,而是在model.fetch() 之后;语句执行,模型中的数据会显示出来,为什么?我真的不知道 fetch 是如何工作的,我试图找出答案,但没有机会。

4

1 回答 1

48

我不完全确定您的问题是什么,但我会尽我所能解释。

urlRoot 背后的概念是基本 URL 和子元素将在其下方获取,并将 id 添加到该 urlRoot。

例如,下面的代码:

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

将设置基本网址。然后,如果您要实例化它并调用 fetch():

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

它将提出以下要求:

GET /accounts/abcd1234

在您的情况下,您正在设置 urlRoot,然后显式设置一个 url,因此您提供的 urlRoot 将被忽略。

我鼓励您查看 Backbone 源代码(它非常简洁)以了解 url 是如何派生的:http: //backbonejs.org/docs/backbone.html#section-65

要回答您的另一个问题,您的个人资料信息不会立即显示的原因是 fetch() 进入网络,进入您的服务器,并且必须等待回复才能显示。

这不是即时的。

它以非阻塞方式完成,这意味着它将发出请求,继续做它正在做的事情,当请求从服务器返回时,它会触发一个事件,Backbone 使用该事件来确保必须执行的任何其他操作完成,现在你已经有了模型的数据,就完成了。

我在您的代码段中添加了一些评论来解释这里发生了什么:

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();
}

因此,如果您想确保在获取模型后更新您的视图,您可以通过以下几种方法来做到这一点:(1) 将成功回调传递给 model.fetch() (2) 在您的视图手表上注册一个处理程序'sync' 事件,在返回时重新渲染视图 (3) 将用于实例化视图的代码放入成功回调中,这样在网络请求返回并且您的模型有数据之后才会创建视图.

于 2013-05-14T14:49:39.960 回答