在使用Backbone进行多个异步ajax调用后呈现视图

时间:2013-09-20 21:00:46

标签: jquery ajax backbone.js

我有一个骨干视图,我想渲染html AFTER 2异步调用:

initialize: function (model, options) {        
    team.fetch({
                success: function (collection) { 
                  //do some things            
           });

    goal.fetch({
                success: function (collection) { 
                  //do some things          
           });

    this.render();
}

    render: function () {
        this.$el.html(template());
        return this;
    }

显然,使用上面的代码,html模板将在ajax调用之前/期间返回。通常,当只有一个ajax调用时,我会这样做:

initialize: function (model, options) {      
    var that = this;
    team.fetch({
                success: function (collection) { 
                  //do some things     
                          that.render();
           });


}

    render: function () {
        this.$el.html(template());
        return this;
    }

使用多个ajax调用执行此操作的最佳方法是什么?

2 个答案:

答案 0 :(得分:3)

我会使用JQuery Deferred实施,特别是$.when。这使您只有在完成多个异步操作时才执行操作。像这样使用它:

var ajax1 = team.fetch({ ... });
var ajax2 = goal.fetch({ ... });

$.when( ajax1, ajax2 ).done( this.render );

修改

正如@muistooshort指出的那样,你还必须绑定render,以便使用正确的上下文调用它(否则this内的render将引用ajax对象而不是视图对象):

_.bind(this.render, this);

答案 1 :(得分:1)

这样你就可以理解jQuery Deferred正在拯救你的东西,这是一个如何在没有它的情况下解决这个常见问题的例子。 (想象一下,为4个集合/模型编写相同的代码,而不仅仅是2个。)

initialize: function(model, options) {
    team.fetch();
    goal.fetch();

    this.listenTo(team, 'sync', this.teamFetched);
    this.listenTo(goal, 'sync', this.goalFetched);
},

teamFetched: function() {
    this._teamFetched = true;
    // if goal also fetched, call & return this.render()
    return (( this._goalFetched ) ? this.render() : this);
},

goalFetched: function() {
    this._goalFetched = true;
    // if team also fetched, call & return this.render()
    return (( this._teamFetched ) ? this.render() : this);
}

render: function() {
    this._goalFetched = this._teamFetched = false;

    this.$el.html(template());
    return this;
}