user3821383
user3821383

Reputation: 31

Nested composite views in marionette

When dealing with Marionettes different views, is it possible to have a composite view calling another composite view calling an item view? For instance, the structure could be a list of objects, each object having a list of attributes:

ObjectList = Marionette.CompositeView.extend({
    template: "#objectlist-template",
    childView: Object,
    initialize: function(){
    }
});

Object = Marionette.CompositeView.extend({
    template: "#object-template",
    childView: Attribute
    initialize: function(){
    }
});

Attribute = Marionette.ItemView.extend({
    template: "#attribute-template",
});

I tried doing this in my project, but it doesn't seem to work:

var objectListView = new ObjectList({
   collection: objects
});

How should the objects collection be structured?

Upvotes: 0

Views: 177

Answers (1)

christian314159
christian314159

Reputation: 639

This is totally possible, but you will need some extra wiring. I think it's generally not considered best practice to have a collection with models that have attributes that are another collection. I don't completely know your use-case so I will assume your attributes are just an array of strings and not something more complex.

You should also refrain from using variable names like Object, Attribute, etc. as those clash with/are very close to reserved words. I renamed the views in my example.

So mainly, in your ItemView you need to create the collection using an attribute of your model:

var ItemListView = Marionette.CompositeView.extend({
    template  : "#objectlist-template",
    childView : ItemView
});

var ItemView = Marionette.CompositeView.extend({
    template   : "#object-template",
    childView  : ItemAttributeView
    initialize : function(){
        // Assuming 'itemAttributes' is something like ['red','yellow','green']
        var itemAttributes = this.model.get('itemAttributes');

        // Map itemAttributes to be objects to instantiate models
        // `name` can then be used in the attribute's template
        itemAttributes = _.map(itemAttributes, function(ia){ return { name : ia }; });

        // use this array to set the collection for this compositeview
        this.collection = new Backbone.Collection( itemAttributes );
    }
});

var ItemAttributeView = Marionette.ItemView.extend({
    template: "#attribute-template",
});

Upvotes: 1

Related Questions