In a Marionette CollectionView, how can I pass the index of the model (in the collection) to the ItemView?
Asked Answered
M

3

6

I have a CollectionView

class MyCollectionView extends Backbone.Marionette.CollectionView
  itemView: MyItemView

  itemViewOptions: ->
    {
      indexInCollection: ?
    }

And I want MyItemView to know at which index in the collection its model is at.

I suppose, in the MyItemView, I can find it out via

@model.collection.indexOf(@model)

But is there a way to pass it in directly into MyItemView from my Marionette CollectionView, using some internal Marionette mechanism? Is this index exposed somewhere already?

Mcinnis answered 20/3, 2013 at 5:26 Comment(0)
L
13

the itemViewOptions, when set up as a function, receives an item or model parameter. Use this to find the index:


class MyCollectionView extends Backbone.Marionette.CollectionView
  itemView: MyItemView

  itemViewOptions: (model) ->
    {
      indexInCollection: this.collection.indexOf(model)
    }
Lollis answered 20/3, 2013 at 13:59 Comment(4)
Ah perfect - I knew there must have been something elegant like this. Thanks Derick.Mcinnis
It's awesome when the creator himself answers!Gambrill
This is out of date. See link below for Marionette v2.0 + https://mcmap.net/q/1595430/-in-a-marionette-collectionview-how-can-i-pass-the-index-of-the-model-in-the-collection-to-the-itemview . The new parameter is now childViewOptions.Tifanie
Also, the second parameter to childViewOptions is the index, no need for the collection.indexOf bitInvolve
W
7

Since Marionette 2.0.0 you can do it with a childViewOptions function:

var CollectionView = Marionette.CollectionView.extend({
  childViewOptions: function(model, index) {
    // do some calculations based on the model
    return {
      foo: "bar",
      childIndex: index
    }
  }
});

As explained in the Marionette documentation for childViewOptions

Weakly answered 1/4, 2015 at 23:44 Comment(0)
P
1

Just adding to the previous answer, if you want to use one of the options in one of your view templates, you can simply do it like this:

class Run.Question extends Backbone.Marionette.ItemView
    template: "mock/run/question"
    initialize: ->
        @model = @model.set index: @options.index

class Run.Content extends Backbone.Marionette.CompositeView
    template: "mock/run/content"
    itemView: Run.Question
    itemViewContainer: "div.data-box"
    itemViewOptions: (model) ->
        {
            index: @collection.indexOf(model) + 1
        }

This way, you can get access to the "index" variable in your template.

Preexist answered 26/11, 2013 at 14:26 Comment(1)
Probably better to override serializeData and expose the index var to the template from there.Stillness

© 2022 - 2024 — McMap. All rights reserved.