简体   繁体   中英

How do I get the model for the selected <option> in a Marionette.js CollectionView?

I have a Marionette CollectionView that renders an ItemView into a <select> menu, with each ItemView rendering as an <option> . My question is, when I call the 'change' event on the CollectionView (meaning the user has selected an option), how do I get the model of the selected <option> from the ItemView?

var singleView = Marionette.ItemView.extend({
        template: '#optionTemplate',
        tagName: 'option'
    });

var listView = Marionette.CollectionView.extend({
        itemView: singleView,
        tagName: 'select',
        id: 'my-selector',
        events: {
            'change': 'optionSelected'
        },
        optionSelected: function() {
          // I need to get the model from within this function

        }
    });

The cleanest approach is to render the option tag with the ID of the corresponding model as the value: <option value="42">Forty Two</option> . Then, on change, get that value and use it to retrieve the model from the collection by ID with collection.get(id) . Some elements like option have a natural attribute that makes sense to be the model ID, but for other elements you can just use a data-id="42" attribute.

Another approach that is viable although I think less simple and clean than the above would be to use jQuery's .data method or equivalent to associate the model instance with the element.

No need to add custom IDs and such, and also danmactough's answer doesn't work so best ignore it. Even childEvents in Marionette won't work with select/option tags.

My method would be to just bind to the change event on the CollectionView and match the index of model within the collection and the :selected element within the dropdown:

var listView = Marionette.CollectionView.extend({
    itemView: singleView,
    tagName: 'select',
    id: 'my-selector',
    events: {
        'change': 'optionSelected'
    },
    optionSelected: function() {
      // The selected model:
      var model = this.collection.at($(':selected', this.$el).index()));
    }
});

I think a better, Marionette-specific solution would be to use the modelEvents or collectionEvents configuration hash available in a CollectionView or CompositeView .

var listView = Marionette.CollectionView.extend({
    itemView: singleView,
    tagName: 'select',
    id: 'my-selector',
    modelEvents: {
        'change': 'modelChanged'
    },
    modelChanged: function(e) {
      // "e" is the event
      // "this" is the ItemView
      // "this.model" is the model  
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM