简体   繁体   中英

Ember: property in array controller computed from property of item controller

I have a typical ArrayController / ObjectController setup as follows:

App.PlayersController = Ember.ArrayController.extend({
  itemController: 'playerItem',
  visibleCount: function(){
     //How do I compute this property?
  }.property(...),
});


App.PlayerItemController = Ember.ObjectController.extend({
  needs: 'players',
  visible: function(){
     ...
  }).property('...')
})

The visible property is computer on the PlayerItemController , but I want to have a global count of visible players from the visibleCount in the PlayersController . How do I achieve this?

Here's what I've tried:

visibleCount: function(){
  return this.get('content').filter(function(p){
    return p.get('visible')
  }).length;
 }.property('content.@each.visible'),

This doesn't work, as p.get('visible') returns undefined every time and the property returns 0 .

You can trigger this completely off the array controller instance itself, since that's where the itemController is defined. Any time you attempt to iterate the this inside the array controller you will get the individual item controllers.

This makes just as much since when you think about it in the context of the template. If you iterate the controller, you get the item Controllers

{{#each item in controller}}
  yay I have an item controller
{{/each}}

whereas if you just iterate the model/content you just get that record back

{{#each item in model}}
  boo, boring model
{{/each}}

App.PlayersController = Ember.ArrayController.extend({
  itemController: 'playerItem',
  visibleItems: Em.computed.filterBy('','visible', true),
  // you don't need this below, you could just do, `visibleItems.length` in the template
  visibleCount: Em.computed.alias('visibleItems.length'),

  // showing off getting item controller
  randomProp: function(){
    this.forEach(function(ic){
      console.log(ic.get('visible'));
    });
  }.property('@each.visible')
});

Example: http://emberjs.jsbin.com/dalazawe/1/edit

It's really cool if you think of it in the way it's implemented. Essentially the array controller overrides how it returns items from the controller to you. When you attempt to get objectAt(1) , if you've defined an itemController it will wrap the underlying object in the itemController and return it. Or if you haven't defined an itemController , it just returns the object to you. Most people are stuck on it just being how it's implemented in the template but that's just half of it, it's how the array controller returns objects to you.

Example: http://emberjs.jsbin.com/dalazawe/2/edit

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