Ember.js: Calculate the sum of a property of all child models

前端 未结 3 1382
醉梦人生
醉梦人生 2021-02-07 10:57

My application has the following models:

App.Store = DS.Store.extend({
    revision: 11,
    adapter: \'DS.FixtureAdapter\'
});

App.List = DS.Model.extend({
            


        
相关标签:
3条回答
  • 2021-02-07 11:18

    The following should do it. There might be an more concise solution using reduce, but i have never used it myself :-)

    App.List = DS.Model.extend({
        name: DS.attr('string'),
        users: DS.hasMany('App.User'),
        tweetsUnread: function(){
            var users = this.get("users");
            var ret = 0;
            users.forEach(function(user){
                ret += users.get("tweetsUnread");
            });
            return ret;
        }.property("users.@each.tweetsUnread")
    });
    

    Update: This is a more elegant solution using reduce. I have never used it and this isn't tested but i am quite confident that this should work:

    App.List = DS.Model.extend({
        name: DS.attr('string'),
        users: DS.hasMany('App.User'),
        tweetsUnread: function(){
            var users = this.get("users");
            return users.reduce(0, function(previousValue, user){
                return previousValue + users.get("tweetsUnread");
            });
        }.property("users.@each.tweetsUnread")
    });
    

    In Ember 1.1 the API for reduce has changed! Thx @joelcox for the hint, that the parameters initialValue and callback have changed their position. So here the correct version of the code:

    App.List = DS.Model.extend({
        name: DS.attr('string'),
        users: DS.hasMany('App.User'),
        tweetsUnread: function(){
            var users = this.get("users");
            return users.reduce(function(previousValue, user){
                return previousValue + user.get("tweetsUnread");
            }, 0);
        }.property("users.@each.tweetsUnread")
    });
    
    0 讨论(0)
  • When using coffeescript, I like to use the one-line syntax, first getting the property values array with .mapBy('propertyName') and then using a simple coffeescript reduce:

    @get('users').mapBy('tweetsUnread').reduce (a, b) -> a + b
    
    0 讨论(0)
  • 2021-02-07 11:29

    Another option would be to use Ember.computed.sum see here

    App.List = DS.Model.extend({
      name: DS.attr('string'),
      users: DS.hasMany('App.User'),
    
      tweetsUnread: Ember.computed.mapBy('users', 'tweetsUnread'),
      totalTweetsUnread: Ember.computed.sum('tweetsUnread')   
    });
    
    0 讨论(0)
提交回复
热议问题