1
votes

I have a marionette composite view called IndexView(). It is tied to a handlebars template called index.html.

Before I continue I will note that I understand that I can simply render an item view tied to the composite view to output each model in the collection. I will be doing this but I want to ask my question for my understanding.

I fetch a collection from a url "/api/users"

and get a list like this

[{"name": "John Doe", "age": 30 }, {"name":"Jane Doe", "age": 31}]

in my users controller I have the code

var usersCollection = new UsersCollection();
App.contentRegion.show(new IndexView({collection: usersCollection}));
usersCollection.fetch();

How do I iterate through the collection in the template?

e.g.

{{#each ????}}
    <li> {{name}} {{age}} </li>
{{/each}}

What would go where the question marks are? From the marionette documentation for an ItemView it would be items. What would it be for a CollectionView or a CompositeView?

2
Can you post your IndexView code?Erik Ahlswede
It's simply Marionette.CompositeView.extend({template: Template}); It's in a require module so posting it here won't give you many details. This question was just for me to see if there was a way to do this. I actually don't have any intentions to use the Composite view this way I was just curious.decapo

2 Answers

2
votes

You don't iterate over the collection in the template. The CompositeView loops over the collection internally and renders an ItemView for each model in the collection. Each ItemView receives a model from that collection as its data. Each individual ItemView is then rendered with the model attributes being passed to the template. So for the ItemView's template, you don't need to loop over each item as the context only represents a single item (model). Hence you template will simply be:

<li> {{name}} {{age}} </li>
<li> {{someOtherAttribute}} </li>
<li> {{andYetAnotherAttribute}} </li>

EDIT: If you want to iterate over the collection in your template, then don't use a CollectionView. Pass the collection to an ItemView like this:

view = new ItemView({collection: myCollection});

The ItemView will pass the collection as an array of models to the template in the items property of your template context. So your template would be:

{{#each items}}
    <li> {{name}} {{age}} </li>
{{/each}}

As the ItemView is now handling all models, your events will no longer be for a single model but the entire collection.

0
votes

Marionette.CompositeView uses buildItemView() build in method to add collection's model to its item view.

It also has a function called serilizeData which native implementation looks like:

// Serialize the collection for the view.
// You can override the `serializeData` method in your own view
// definition, to provide custom serialization for your view's data.

Marionette.CompositeView = Marionette.CollectionView.extend({
    // composite view implementation
    serializeData: function() {
        var data = {};
        if (this.model) {
            data = this.model.toJSON();
        }
        // your case
        // data.myCollection = this.collection.toJSON();
        // then use myCollection in your template in place of ????
        return data;
    }
    // composite view implementation
});

You can override this to pass any object or collection of object to compositeView template.

As I know there is no other build in method to access collection directly from template for this case.