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

时间:2012-02-12 16:40:30

标签: javascript asynchronous backbone.js

我试图了解backbone.js的一部分是如何工作的。一旦应用程序开始,我必须获取一组模型。我需要等到fetch完成才能呈现每个视图。 我并非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);
    }
});    

6 个答案:

答案 0 :(得分:64)

我使用的方法是jQuery完全回调,如下所示:

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

这是在Backbone bug report中推荐的。虽然错误报告建议使用complete,但该回调方法已deprecated支持done

答案 1 :(得分:24)

您也可以使用jquery 1.5 +

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

答案 2 :(得分:10)

您可以将自己的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键传入,则在将集合解析为模型并添加到集合中后,它将调用它。

所以,如果你这样做:

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

(假设initialize方法绑定this.do_somethingthis ...),它将在整个shebang之后调用该方法,允许您在获取后立即触发操作解析/附

答案 3 :(得分:1)

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

加载自举模式

当您的应用首次加载时,为了呈现页面,通常会有一组您知道自己需要的初始模型。一个更好的模式是将其数据引导到页面中,而不是触发额外的AJAX请求来获取它们。然后,您可以使用reset使用初始数据填充集合。在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>

答案 4 :(得分:1)

另一种选择是在集合初始化方法中添加以下内容:

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

每当提取完成和/或以编程方式更新集合时,这将触发render方法。

答案 5 :(得分:0)

您可以使用开启和关闭方法

如果你想添加触发器方法,比如假设你想要成功,你想调用render方法,所以请按照下面的例子。

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