Marionette.js在CollectionView中渲染具有不同模型+模板的多个ItemView

时间:2014-04-19 23:18:07

标签: javascript backbone.js marionette collectionview

我试图围绕如何在CollectionView中渲染多个ItemView,每个ItemView都有一个独特的模型和模板。 Marionette.js文档指定CollectionView支持单个ItemView。我做出这个假设是错误的还是CollectionView支持这个?如果没有,推荐什么?提前感谢您的帮助。

更新:

我添加了以下代码:

privObj.propertiesSubPanelView = new Marionette.CollectionView({
                    el: options.el,
                    collection: col,
                    getItemView: function( item ) {
                        console.log( item );
                    }
                });
privObj.propertiesSubPanelView.render.done( function() {
    console.log( 'Im done' );
});

发出以下错误:

An `itemView` must be specified

更新#2:

我在CollectionView中实现了getItemView函数,如下所示:

var ColView = Marionette.CollectionView.extend({
    collection: col,
    itemViews: views,

    getItemView: function( item ) {
        var viewId,
        itemViewObj,
        itemView;

        viewId = item.get( 'name' );
        itemViewObj = Marionette.getOption( this, 'itemViews' );
        itemView = itemViewObj[viewId];

        if ( _.isUndefined( itemView ) ) {
            throw new Error( 'No view associated with name: ' + viewId );
        }
        return itemView;
    }
});

var colView = new ColView();

var propLayout = new PropLayout();
propLayout.properties.show( colView );

但是,我没有得到以下错误(Uncaught TypeError:object不是函数):

Marionette.CollectionView.buildItemView: function(item, ItemViewType, itemViewOptions){
    var options = _.extend({model: item}, itemViewOptions);
    return new ItemViewType(options); <<== this line!
}

我错过了什么或这是一个错误吗?

更新#3

这是我的主要功能......

           newPropertiesSubPanelCollection: function( col, views ) {
                var labelModel1 = new Backbone.Model({
                    name: 'Properties',
                    value: 'Properties',
                    data: undefined
                });
                var labelView1 = new Label_.Item();

                var labelModel2 = new Backbone.Model({
                    name: 'Configure',
                    value: 'Properties',
                    data: undefined
                });
                var labelView2 = new Label_.Item();

                var col = new Backbone.Collection();
                col.add( labelModel1 );
                col.add( labelModel2 );

                var views = {};
                views['Properties'] = labelView1;
                views['Configure'] = labelView2;

                var ColView = Marionette.CollectionView.extend({
                    collection: col,
                    itemViews: views,

                    getItemView: function( item ) {
                        var viewId,
                            itemViewObj,
                            itemView;

                        viewId = item.get( 'name' );
                        itemViewObj = Marionette.getOption( this, 'itemViews' );
                        itemView = itemViewObj[viewId];

                        if ( _.isUndefined( itemView ) ) {
                            throw new Error( 'No view associated with name: ' + viewId );
                        }
                        return itemView;
                    }
                });
                var colView = new ColView();
                return this.propertiesSubPanelCollection = colView;
            },

3 个答案:

答案 0 :(得分:1)

查看https://github.com/marionettejs/backbone.marionette/blob/master/src/marionette.collectionview.js的来源,我们可以看到:

getItemView: function(item){
    var itemView = Marionette.getOption(this, "itemView");

    if (!itemView){
        throwError("An `itemView` must be specified", "NoItemViewError");
    }
    return itemView;  
},  

这意味着它默认会查找itemView属性。但是,如果您覆盖此功能(正如David Sulc所说),您可以在此处执行任何操作。如果您愿意,可以提供包含视图的对象,例如:

privObj.propertiesSubPanelView = Marionette.CollectionView.extend({
    el: options.el,
    itemViews: {
        view1: itemView1,
        view2: itemView2 // etc..
    }
    getItemView: function( item ) {
        // Get the view key for this item
        var viewId = item.get('viewId');

        // Get all defined views for this CompositeView
        var itemViewObject = Marionette.getOption(this, "itemViews");

        // Get correct view using given key
        var itemView = itemViewObject[viewId];


        if (!itemView){
            throwError("An `itemView` must be specified", "NoItemViewError");
        }
        return itemView;
    }
});

// Create view instance
var viewInstance = new privObj.propertiesSubPanelView({
    collection: col
});

// Your model might have the following attribute
model.get('viewId'); // returns 'view1';

您的问题中还有另一个错误,即new Marionette.CollectionView({。你不能这样做,见上面的例子。在调用new关键字之前,您需要先扩展视图。

添加了一个演示上述代码的jsFiddle:http://jsfiddle.net/Cardiff/L8xG9/

答案 1 :(得分:0)

答案 2 :(得分:0)

这是一些旧的骨干和木偶图书馆的问题。我使用了以下库,它解决了这个问题。

https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.2/backbone-min.js https://cdnjs.cloudflare.com/ajax/libs/backbone.marionette/2.4.5/backbone.marionette.min.js