【问题标题】:Rendering a view after multiple asynchronous ajax calls with Backbone在使用 Backbone 进行多次异步 ajax 调用后渲染视图
【发布时间】:2013-09-20 21:00:45
【问题描述】:

我有一个主干视图,我想在 2 个异步调用之后呈现 html:

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 调用最优雅的方法是什么?

【问题讨论】:

    标签: jquery ajax backbone.js


    【解决方案1】:

    我会使用JQuery Deferred 实现,特别是$.when。这使您仅在完成多个异步操作时才采取行动。像这样使用它:

    var ajax1 = team.fetch({ ... });
    var ajax2 = goal.fetch({ ... });
    
    $.when( ajax1, ajax2 ).done( this.render );
    

    编辑

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

    _.bind(this.render, this);
    

    【讨论】:

    • 会在正确的上下文中调用render 吗?我认为待定的编辑正试图解决这个问题。
    • 只是好奇,在没有 this/self 上下文存储的情况下,渲染是否会有最后一个 ajax 调用的上下文来完成?
    • @CoryDanielson 哦,很好的捕捉......自我/这种隐藏在那里没有必要。
    • 谢谢,它的工作。请注意, .done 必须采用匿名函数,否则它会立即计算并在 ajax 调用完成之前调用 render 。我添加了一个待处理的编辑
    • @user1716672 如果您使用.done(this.render),不带括号,它是否有效?我认为这是正确的。
    【解决方案2】:

    只是为了让您了解 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;
    }
    

    【讨论】:

      猜你喜欢
      • 2018-09-23
      • 1970-01-01
      • 2015-05-30
      • 2013-08-07
      • 2013-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多