如何在Marionette中处理异步请求?

时间:2015-03-07 09:02:29

标签: marionette

我正在尝试使用2个API请求的组合结果填写Marionette中的ItemView。

  this.standings = App.request('collection:currentStandings');
  this.userInfo = App.request('model:userInfo');
  this.standings.each(function(s) {
    if (s.currentUser) {
      s.set('alias', this.userInfo.alias);
      s.set('imageURL', this.userInfo.imageURL);
    }
  });
  userInfoView = new LeagueBar.UserInfo({ collection: this.standings });

问题是,组合永远不会发生,因为在我尝试将它们组合之前,请求尚未完成。

我知道我可能需要为每个请求添加一个承诺,但我找不到干净的方法来做到这一点。我可以使'collection:currentStandings'和'model:userInfo'返回promises,但是,它们目前在代码的许多其他部分使用,所以我必须返回并添加.then()和.done()在以前不需要它们的代码库中。

有任何想法或建议吗?

编辑:

我目前以一种不太理想的方式解决了这个问题:我为别名创建了一个模板/视图,为imageURL创建了一个模板/视图,并为榜样信息保留了模板/视图。这似乎不是最好的方式,我很想知道解决这个问题的正确方法。

这是我想要合并的两个请求:

Models.CurrentStandings = App.Collection.extend({
    model: Models.PlayerStandings,
    url: function() { return 'leagues/' + App.state.currentLeague + '/standings'; },
    parse: function(standings) {
        return _.map(standings, function(s) {
            if (s.memberId == App.user.id)
                s.currentUser = true;
            return s;
        });
    }
});

App.reqres.setHandler('collection:currentStandings', function() {
    weekStandings = new Models.CurrentStandings();
    weekStandings.fetch({ success: function(data){ console.log(data); }});
    return weekStandings;
});

Models.UserInfo = App.Model.extend({
    url: 'users/me'
});

App.reqres.setHandler('model:userInfo', function(options) {
    myuser = new Models.UserInfo();
    myuser.fetch(options);
    return myuser;
});

1 个答案:

答案 0 :(得分:0)

根据您在视图之间的依赖关系,有两种解决方案可供选择:

  1. 您可以创建处理Models.UserInfo的“更改”事件的视图,并在数据准备就绪时(引发更改/重置事件)重新呈现内容。这可能是你的解决方案。
  2. 如果您正在寻找一个不应该创建LeageBar.UserInfo实例的解决方案,直到Models.CurrentStanding和Models.UserInfo都准备就绪,您必须返回获取函数的结果,所以你可以从setHandlers中删除调用fetch并使用它们如下:

    this.standings = App.request('collection:currentStandings');
    this.userInfo = App.request('model:userInfo');
    var that=this;
    that.standings.fetch().done(function(){
        that.userInfo.fetch().done(function(){
            that.standings.each(function(s) {
                if (s.currentUser) {
                    //....
                }
            });
    
            userInfoView = new LeagueBar.UserInfo({ collection: that.standings });
    });