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

Javascript 如何等待在backbone.js中呈现视图,直到获取完成?,javascript,asynchronous,backbone.js,Javascript,Asynchronous,Backbone.js,我试图理解backbone.js的一部分是如何工作的。应用程序启动后,我必须获取一组模型。我需要等到提取完成后才能渲染每个视图。 我不是100%确定在这种情况下采取的最佳方法 var AppRouter = Backbone.Router.extend({ routes: { "": "home", "customer/:id": "customer" }, home: function () { console.log

我试图理解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);
    }
});    

您可以将自己的options.success发送到collections获取方法,该方法仅在获取完成时运行


编辑(超晚!)

来自主干网源(0.9.1中的起始线624)

注意倒数第二行。如果您已将
选项
对象中的函数作为
成功
键传递,它将在集合解析为模型并添加到集合后调用该函数

因此,如果你这样做:

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

(假设
initialize
方法绑定
this.do\u something
this
…),它将在整个shebang之后调用该方法,允许您在获取/解析/附加后立即触发操作您也可以使用jquery 1.5执行此操作+

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

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

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

这是在主干网中推荐的。尽管bug报告建议使用
complete
,但该回调方法一直支持
done

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

加载引导模型

当您的应用程序首次加载时,通常会有一组您知道需要的初始模型,以便呈现页面。更好的模式是将数据引导到页面中,而不是触发额外的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>

var账户=新主干。集合;
Accounts.reset();
var Projects=新主干网集合;
项目。重置(正确)%>);

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

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

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

您可以使用on和off方法。

若你们想添加触发器方法,比如假设,若你们想成功,你们想调用render方法,所以请遵循下面的例子

    _this.companyList.on("reset", _this.render, _this);
    _this.companyList.fetchCompanyList({firstIndex: 1, maxResult: 10},     _this.options);
在模型js中,请使用like

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

你知道你要提前拿到多少东西吗?为什么要等到它们全部关闭后再渲染呢。您不能将页面设计为允许每个对象呈现自己并将其附加到Dom吗?当我尝试运行this.customers.at(2)并抓取第二个对象时,它总是返回未定义的对象,除非我等待在获取时触发成功。我想,这是我做错了,没有完全理解。我对JScript.FYI还很陌生。这是JavaScript而不是jscript。Jscript是微软的私生子变体。但是yesfetch是非阻塞的,这意味着如果调用fetch,那么无论fetch的结果如何,下一个命令都将运行。看看下面我的答案。我正在打电话等着修车:)。等我回家就行了!仅供参考,主干源代码有很好的注释和注释。你可能想同时看看fetch Great。非常感谢你的帮助@tkone还在你的手机上吗?:)@斯科特格林菲尔德哇,我忘了那个。这就是我所说的。我不希望我的模型或集合在我的主干定义JS文件中有任何对视图的引用。这种方法可以避免这种情况。谢谢这是超级简单,工作完美。我强烈推荐这个答案。迈克尔,你一定也在别处调用了渲染函数。也许在你实例化你的视图之后?我认为在视图本身中渲染视图是不明智的。这很容易出错。@BonifatiusK为什么?那么,你建议改为放置渲染函数的原因是什么?@BonifatiusK你没有回答为什么上述答案中的方法比从其他地方启动渲染函数更容易出错。当然,每个开发人员都应该使用自己的判断,但是这个代码段将所有与视图相关的代码都保存在视图中。在另一个文件中包含与视图相关的代码只会使代码难以解开。但是,在某些情况下,您肯定不希望在获取完成时直接渲染视图,但这正是问题所要求的——一种将渲染延迟到获取完成的方法。我不知道这是存在的。谢谢。我正在尝试这个方法获取收藏,但它不起作用。它给我的是json,而不是一个集合的值:
$。当(collection.fetch())。然后(函数(该值){console.log(该值)})
这是并行逻辑还是串行逻辑?
    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);
            } 
        }
    });
}