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

Marionette.js Rendering Multiple ItemViews With Different Models + Templates In A CollectionView

本文关键字:模型 ItemView CollectionView js Marionette      更新时间:2023-09-26

我正试图了解如何在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 );

然而,我在中没有得到以下错误(未捕获的类型错误:对象不是函数)

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

是我错过了什么,还是这是个bug?

更新#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;
            },

查看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/

您可以定义getItemView以根据您的模型返回不同的项目视图:https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.collectionview.md#collectionviews-getitemview

这是一些旧的主干和Marionette库的问题。我使用了以下库,它解决了这个问题。

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