0
votes

I have a list of products that I'd like to add to an array on another controller for messages. I have created an objectcontroller for the product model so that I can toggle a "selected" attribute (which is working fine) but my observer in the message controller isn't firing. Heres the objectcontroller for the product:

App.ProductController = Ember.ObjectController.extend({
    selected: false,
    actions:{
        toggleSelected: function(){
            this.set('selected', !this.get('selected'));
        }
    }
});

Here's the message controller -- the products are just for a test, but do I (/can I) declare an itemcontroller for a list like this?

App.MessagesNewController = Ember.Controller.extend({
    needs: ['product'],
    products: [{name: 'product 1', id: 1}, {name: 'product 2', id: 2}],
    selectedProducts: function(){
        var products = this.get('products');
        return products.filterBy('selected', true);
    }.observes('[email protected]')

});

and the template:

{{#each product in products itemController="product"}}
    <div {{bind-attr class=":well product.selected"}} {{action 'toggleSelected'}}>
        {{product.name}}
    </div>
{{/each}}

I'm very new to Ember so I appreciate any direction or best-practices for this type of thing. Thanks

Note: I'm using ember-data also, if that makes any difference.

2

2 Answers

1
votes

You're almost there you are just missing a few things...

1) The data should be loaded in the model hook of the `Route. Like this...

App.MessagesRoute = Ember.Route.extend({
  model: function(){
    return [{name: 'product 1', id: 1}, {name: 'product 2', id: 2}]
  }
});

2) The App.MessagesController should be an Ember.ArrayController since it's wrapping an array of data. Like this...

App.MessagesController = Ember.ArrayController.extend() 

3) You can specify the itemController property on the App.MessagesController so that it wraps each item in the array in an item controller.

If you followed all those steps then you would be able to loop through the items in the template by doing something like...

{{#each}} <-- if you dont specify what to loop through
              it will loop through the arrayControllers items
              which in this case will be the products wrapped in 
              an itemController
  {{name}}
{{/each}}

you would also be able to get the selected items by doing something like...

this.filterBy('selected', true);

To put it all together it would look like...

App.MessagesRoute = Ember.Route.extend({
  model: function(){
    return [{name: 'product 1', id: 1}, {name: 'product 2', id: 2}]
  }
});

App.ProductController = Ember.ObjectController.extend({
    actions:{
        toggleSelected: function(){
            this.toggleProperty('selected');
        }
    }
});

App.MessagesController = Ember.ArrayController.extend({
    itemController: 'product',
    selectedProducts: function(){
        return this.filterBy('selected', true);
    }.property('@each.selected')

});

working bin here: http://emberjs.jsbin.com/jucab/2/edit

1
votes

You need to initialize the property selected on the products, otherwise it will not propagate back to them when you toggle the property on the controller. See http://emberjs.jsbin.com/kiludiwutuyu/1/edit?html,js,output for a working example.

Hope this helps.