jrabary
jrabary

Reputation: 2441

Does it make sense to use ObjectController and ArrayController together?

I have a list of object, stored in an arrayController and rendered on the view using the #each macro

{{#each item in controller}}
  {{view App.ItemView}}
{{/each}}

Each item view has class name binding that depends on the user action. For exemple :

App.ItemView = Ember.View.extend {
  classNameBindings: ['isSelected:selected']
}

isSelecteddepends on the state of each Item : I have to store the selected item somewhere, and compare it to the new selected item if a click event is triggered.

The question is: where should I compute this isSelectedproperty ? In the itemsController ? In an itemController? Directly in each itemView ?

Upvotes: 1

Views: 1360

Answers (2)

Mike Aski
Mike Aski

Reputation: 9236

To me, it does make sense to put it into the view as, moreover, it is really a display concern.

You've got an example here: http://jsfiddle.net/MikeAski/r6xcA/

Handlebars:

<script type="text/x-handlebars" data-template-name="items">
    {{#each item in controller}}
        {{view App.ItemView contentBinding="item"}}
    {{/each}}
</script>

<script type="text/x-handlebars" data-template-name="item">
    Item: {{item.label}}
</script>

​JavaScript:

App.ItemsController = Ember.ArrayController.extend({
    selected: null
});

App.ItemsView = Ember.View.extend({
    templateName: 'items'
});

App.ItemView = Ember.View.extend({
    templateName: 'item',
    classNameBindings: ['isSelected:selected'],

    isSelected: function() {
        var item = this.get('content'),
            selected = this.getPath('controller.selected');
        return item === selected;
    }.property('item', 'controller.selected'),

    click: function() {
        var controller = this.get('controller'),
            item = this.get('content');
        controller.set('selected', item);
    }
});

App.ItemsView.create({
    controller: App.ItemsController.create({
        content: [{ label: 'My first item' },
                  { label: 'My second item' },
                  { label: 'My third item' }]
    })
}).append();
​

Upvotes: 3

pjmorse
pjmorse

Reputation: 9304

It sounds like you need two things - an isSelected property on the item itself (the model) which answers the question, "Is this item selected?", and a selectedItem property on the itemsController, which answers the question, "Which item is selected?" The property on the model is just a get/set; you could compute itemsController.selectedItem by filtering the list of items for one where isSelected is true, or you could set it explicitly with some code to un-select previously unselected items.

Upvotes: 0

Related Questions