如何等待在backbone.js中呈现视图,直到抓取完成?

我试图了解backbone.js的一部分是如何工作的。 一旦应用程序启动,我必须获取一组模型。 我需要等到提取完成才能呈现每个视图。 我不是100%确定采取这种情况下的最佳方法。

var AppRouter = Backbone.Router.extend({ routes: { "": "home", "customer/:id": "customer" }, home: function () { console.log("Home"); }, customer: function (id) { if (this.custromers == null) this.init(); var customer = this.customers.at(2); //This is undefined until fetch is complete. Log always says undefined. console.log(customer); }, init: function () { console.log("init"); this.customers = new CustomerCollection(); this.customers.fetch({ success: function () { console.log("success"); // I need to be able to render view on success. } }); console.log(this.customers); } }); 

我最近写了几篇文章。 他们应该帮助:

  • 不知道集合是否加载,从骨干集合中获取模型
  • 用jQuery Deferred重写我的'保证callback'代码

虽然它与观点有关,但这个可以帮助你从另一个angular度理解:

  • asynchronous加载骨干视图的HTML模板

我使用的方法是像这样的jQuery完成callback:

 var self = this; this.model.fetch().done(function(){ self.render(); }); 

这是在Backbone的错误报告中推荐的。 虽然错误报告build议使用complete ,那么callback方法已被弃用 ,赞成done

你也可以用jquery 1.5+来做到这一点

 $.when(something1.fetch(), something2.fetch()...all your fetches).then(function() { initialize your views here }); 

您可以将您自己的options.success发送到仅在提取完成时才运行的集合提取方法


编辑 (超晚!)

从主干源(0.9.1中的起始行624)

 fetch: function(options) { options = options ? _.clone(options) : {}; if (options.parse === undefined) options.parse = true; var collection = this; var success = options.success; options.success = function(resp, status, xhr) { collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options); if (success) success(collection, resp); }; 

注意倒数第二行。 如果你已经在options对象中传递了一个函数作为success键,那么在集合被parsing成模型并添加到集合之后,它将调用它。

所以,如果你这样做:

 this.collection.fetch({success: this.do_something}); 

(假设initialize方法将this.do_something绑定到this …),它会在整个shebang之后调用该方法,允许您在fetch / parse / attach之后立即触发动作

另一个有用的方法可能是在页面加载时直接引导数据。 这个如果从
FAQ :

加载自举模型

当您的应用第一次加载时,通常会有一组您知道您将需要的初始模型,以便呈现页面。 而不是发起一个额外的AJAX请求来获取它们,一个更好的模式是让他们的数据已经引导到页面。 然后您可以使用重置来使用初始数据填充您的集合。 在DocumentCloud中,在工作区的ERB模板中,我们沿着这些线做了一些事情:

 <script> var Accounts = new Backbone.Collection; Accounts.reset(<%= @accounts.to_json %>); var Projects = new Backbone.Collection; Projects.reset(<%= @projects.to_json(:collaborators => true) %>); </script> 

另一个select是在你的集合里面添加下面的initialize方法:

 this.listenTo(this.collection, 'change add remove update', this.render); 

只要提取完成和/或以编程方式更新集合,这将触发呈现方法。

你可以使用on和off方法

如果你想添加触发方法,如果你想成功,你想要调用渲染方法,所以请按照下面的例子。

  _this.companyList.on("reset", _this.render, _this); _this.companyList.fetchCompanyList({firstIndex: 1, maxResult: 10}, _this.options); 

在模型js请使用像

  fetchCompanyList: function(data, options) { UIUtils.showWait(); var collection = this; var condition = "firstIndex=" + data.firstIndex + "&maxResult=" + data.maxResult; if (notBlank(options)) { if (notBlank(options.status)) { condition += "&status=" + options.status; } } $.ajax({ url: "webservices/company/list?" + condition, type: 'GET', dataType: 'json', success: function(objModel, response) { UIUtils.hideWait(); collection.reset(objModel); if (notBlank(options) && notBlank(options.triggerEvent)) { _this.trigger(options.triggerEvent, _this); } } }); }