在Marionette.js的视图中显示集合长度

时间:2015-08-19 14:18:25

标签: javascript backbone.js marionette

我正在学习Marionette.js并有一个场景,我的应用程序有:

app.addRegions({
    main: '#omen',
    newItem: '#addnewitem',
    counter: '#counter'
});

这些地区。我有这些模型/收藏:

var Item = Backbone.Model.extend(),
Items = Backbone.Collection.extend({
    model: Item,
    url: 'api/items'
}),

我有一个项目视图和项目视图:

ItemView = Mn.ItemView.extend({
    tagName: 'tr',
    template: '#itemView',
    events: {
        'click #btnDeleteBook' : 'deleteItem'
    },
    deleteItem: function() {
        app.trigger('item:delete', this.model);
    }
}),
ItemsView = Mn.CollectionView.extend({
    tagName: 'table',
    childView: ItemView,
    onShow: function(view) {
        TweenMax.staggerFrom($(view).find('td'), 1, {
            x: 100
        }, 2);
    }
}),

我有一个初始化函数,它侦听上面的事件并通过app.ItemController完成。一切正常。

但是现在我想添加一个区域(计数器区域),它显示我的集合中的项目总数。理想情况下,我需要将它作为一个单独的视图,因为我将在不同的地方显示它。

所以我这样做:

DisplayCounter = Mn.ItemView.extend({
    template: _.template('Total: '+ app.Items.length),
}),

app.Items是上面声明的Collection的实例。但即使在实例化DisplayCounter之前,我也会收到错误:

未捕获的TypeError:无法读取属性'长度'未定义的。

请帮助...... :(

------------------------- EDIT --------------------- -

我已经实现了它,但做这么小的事情似乎太复杂了。

改变了我的收藏:

Items = Backbone.Collection.extend({
        model: Item,
        url: 'api/items',
        initialize: function() {
            this.listenTo(this, 'add', function() {
                app.trigger('collection:updated', this);
            });
        }
    }),

并改变了我的DisplayCounter:

DisplayCounter = Mn.ItemView.extend({
        template: _.template('Total: <%=length%>'),
        templateHelpers: function() {
            return {
                length: this.lengthVariable || 0
            }
        },
        initialize: function() {
            app.on('collection:updated', function(params){
                this.lengthVariable = params.length;
                this.render();
            }.bind(this));
        }
    }),

我无法相信没有更简单的方法可以做到这一点..:/

2 个答案:

答案 0 :(得分:1)

设置DisplayCounter的代码在将Items的实例放入app.Items的代码之前运行。

即使您通过先指定app.Items来避免此问题,您仍然会遇到问题 - template属性只设置一次,因此您只能看到长度您定义app.Items时的DisplayCounter

您应该在渲染时提供一个值,而不是将值直接硬编码到模板字符串中。 Mn.View.serializeData允许您自定义在渲染时传递到模板函数的数据:

DisplayCounter = Mn.ItemView.extend({
  template: _.template('Total:: <%= itemCount %>),

  serializeData: function() {
    return { itemCount: app.Items.length }
  }
}),

答案 1 :(得分:0)

app.Items尚未定义。

在Marionette中,您可以定义要使用的视图集合或模型。

ItemsView = Mn.CollectionView.extend({
tagName: 'table',
childView: ItemView,
collection: myItems // An instance of your collection
onShow: function(view) {
    TweenMax.staggerFrom($(view).find('td'), 1, {
        x: 100
    }, 2);
}
}),

所以marionette将在你的集合中为每个元素渲染一个itemView。然后在集合视图this.collection内部将引用集合实例。因此this.collection.length将满足您的需求。

在您的ItemView中,您可以使用this.model

获取相应的模型