0

So what i'm trying to do is the following:

i have an collectionlistview of <li><a>item</a></li> itemviews.

Now the method i use is when i click on item it handles the click in the itemview and adds the class selected, and i use $('.selected').removeClass('selected');

But this doesn't feel right, i've thought several times about how i could this the best way. Maybe i should use events somehow?

Ideas/implementations?

Captain Obvious
  • 745
  • 3
  • 17
  • 39

1 Answers1

1

If each of the views corresponds to a model, then I'd probably select the model and let the view react to a change event on the model:

var MyModel = Backbone.Model.extend({
  select: function () {
      // I add select methods instead of having this 
      // set directly on the model in case I want to 
      // control the event firing, for example if I 
      // want to suppress it
      this.set({ selected: true });
  },
  deselect: function () {
      this.set({ selected: false });
  }
});

// where-ever my view is defined:
var MyView = Marionette.ItemView.extend({
    initialize: function () {
        this.listenTo(this.model, 'change:select', this.toggleSelected);
    },
    toggleSelected: function () {
        this.$el.toggleClass('selected');
    }
});

This keeps the model state decoupled and scopes the view behavior to just the view's concern as well. If you're worried about keeping the selected state of the class in sync with the selected state of the model, you can also trigger the change even from the model select/deselect methods yourself, passing the selected state as an additional option in the trigger method:

select: function () {
    this.trigger('selected', { selected: true });
}

toggleSelected: function (options) {
    this.$el.toggleClass('selected', options.selected);
}

or you can actually query the state of the model when you call toggleClass:

toggleSelected: function () {
    this.$el.toggleClass('selected', this.model.get('selected'));
}
kinakuta
  • 9,029
  • 1
  • 39
  • 48