Backbone Marionette:在ItemView中渲染集合

时间:2014-04-08 23:11:24

标签: backbone.js marionette backbone-views

我无法找到与此错误相关的任何帖子。我试图在Marionette ItemView中渲染Backbone Collection。但是,渲染模板时,与集合相关的数据不会在模板中呈现。我没有错误或其他指标。出于我无法理解的原因,在setTimeout()上使用App.mainRegion.show(overView)。但是,我知道这不是一个可以接受的解决方案。在这种情况下,有人能给我一些关于如何为集合正确渲染的ItemView的一些见解吗?这是我的简化代码:

我要收藏的收藏品:

About.Collection = Backbone.Collection.extend({
    url: '/api/about',
    idAttribute: '_id',
});

参与的视图定义:

About.ListView = Marionette.CollectionView.extend({
    tagName: 'ul',
    itemView: App.About.ListItemView,   
});

About.OverView = Marionette.ItemView.extend({
    tagName: 'div',
    className: 'inner',
    template: _.template('<h2>About Overview</h2><p><%= items %></p>'),
});

我的相关执行代码:

var API = {
    getAbouts: function() {
        var abouts = new App.About.Collection();
        abouts.fetch();
    return abouts;
    },
    ...
}

var abouts = API.getAbouts();

var aboutsListView = new App.About.ListView({collection: abouts }),
aboutsOverView = new App.About.OverView({collection: abouts});

// Correctly renders collection data
App.listRegion.show(aboutsListView);

// Does not render collection data
App.mainRegion.show(aboutsOverView);

// unless
setTimeout(function() {App.mainRegion.show(aboutsOverView)}, 50);

对于那些感兴趣的人,我使用的ItemView最终意图显示About.Collection的汇总数据。如果需要,我很乐意提供更多信息。

2 个答案:

答案 0 :(得分:1)

fetchcollection电话的异步性质存在问题。当您显示两个collection时,views的数据尚未返回。如果您更新代码的执行部分,如下所示(未经测试),您应该在正确的轨道上:

var API = {
    getAbouts: function() {
        // Just return the new collection here
        return new App.About.Collection();
    },
    ...
}

// Fetch the collection here and show views on success
var abouts = API.getAbouts().fetch({
    success: function() {
        var aboutsListView = new App.About.ListView({collection: abouts }),
        aboutsOverView = new App.About.OverView({collection: abouts});

        // Should render collection data now
        App.listRegion.show(aboutsListView);

        // Should render collection data now
        App.mainRegion.show(aboutsOverView);
    }
});

答案 1 :(得分:0)

abouts.fetch调用是异步的,并且在集合从服务器接收数据之前经过了大量时间。这是事情发生的顺序:

  • 您致电getAbouts,它本身会调用abouts.fetch来对服务器进行GET调用以进行收集。
  • 进行listRegion.showmainRegion.show调用,使用空集合呈现2个视图(该集合尚未收到服务器的响应)
  • GET调用最终返回,并使用数据填充集合。
  • 只有aboutsListView 重新呈现以显示数据(请参阅下面的原因)。

只有aboutsListView重新渲染的原因是Marionette CollectionView会自动侦听集合的reset事件,当事件的内容被替换时会触发该事件。

您只需向initialize添加OverView功能即可解决此问题,以便该视图也可以重新呈现以响应同一事件:

// add to About.OverView:

initialize: function() {
    this.listenTo(this.collection, 'reset', this.render);
}

这将照顾它。