2
votes

I have a collectionView that creates a UL using a LI itemView.

I wanted to use the item index number (count) in the underscore template. i.e.:

hello (item 0)
world (item 1)

Does anybody know how to use the count in marionette? i want to avoid putting it in the model.

this is what i would like my itemView template to look like (with n as item count):

<script id="task-template" type="text/html">
          <div class="order"><%=n%></div>
          <div class="title-container">
               <a href="#">...</a>
          </div>
 </script>

any help appreciated,

cheers,

2
It's not clear if you're having an HTML/CSS issue, or a JavaScript issue. Edit your question & post the relevant snippets of JS/Backbone. You'll get a much better answer if you do. If the code gets too long/in-depth post snippets and also make a fiddle.EBarr

2 Answers

9
votes

I have just found a easy way to do it. (with Marionette v1.0.0-rc6)

Using templateHelpers property.

In your item view:

MyItemView = Backbone.Marionette.ItemView.extend({
    template: "#my-item-view-template",

    templateHelpers: function(){

        var modelIndex = this.model.collection.indexOf(this.model);
        return {
            index: modelIndex
        }

    }
});

in your template you can print the index with:

<%= index %>

That's all.

3
votes

This should be easy, as a model in a collection can easily get the information you need. You'll need to create a "view model" wrapper around your model so that you can grab the extra info that you want.


var createViewModel(model){

  // inherit from the original model
  var vm = Object.create(model);

  // override the original `toJSON` method
  vm.toJSON = function(){
    var json = model.toJSON();

    // add the index
    json.index = model.collection.indexOf(model);

    return json;
  }

  return vm;
}

This view model will be used by your itemView, directly.


MyItemView = Backbone.Marionette.ItemView.extend({
  template: "#my-item-view-template",

  initialize: function(){

    // replace the model with the the view model
    this.model = createViewModel(this.model);

  }
});

MyCollectionView = Backbone.Marionette.CollectionView({
  itemView: MyItemView
});

And that's it.

When you pass your collection in to the MyCollectionView constructor and render the collection view, a new view model will be created for each itemView instance, at the time the itemView is instantiated. The template can render the index from the model now.

The view model inherits from the original model directly, so all of the methods and attributes are still available. Overriding the toJSON method allows you to get the original json out of the original model, and then augment it with whatever data you need. Your original model is never modified, but the model that the item view is using has the data you need.