15

我的应用程序具有以下模型:

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

App.List = DS.Model.extend({
    name: DS.attr('string'),
    users: DS.hasMany('App.User'),
    tweetsUnread: function(){
        /////////////////////////////////////////
        // Code to dynamically calculate the sum 
        // of tweetsUnread property of all
        // App.User that are related to this list
        /////////////////////////////////////////
    }
});

App.User = DS.Model.extend({
    screenName: DS.attr('string'),
    tweets: DS.hasMany('App.Tweet'),
    tweetsUnread: function(){
        // TODO: check if this is the correct way to do it
        return this.get('tweets').get('length');
    }.property('tweets.@each'),
    list: DS.belongsTo('App.List')
});

App.Tweet = DS.Model.extend({
    text: DS.attr('string'),
    user: DS.belongsTo('App.User')
});

如何计算所有 App.User.tweetsUnread 的总和并使其自动更新 App.List.tweetsUnread?

4

3 回答 3

40

另一种选择是使用Ember.computed.sumsee 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')   
});
于 2014-12-29T05:00:51.980 回答
15

以下应该做到这一点。使用reduce可能有一个更简洁的解决方案,但我自己从未使用过它:-)

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")
});

更新:这是一个使用 reduce 的更优雅的解决方案。我从未使用过它,也没有经过测试,但我很有信心这应该可以工作:

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")
});

在 Ember 1.1 中,reduce 的 API 发生了变化!感谢@joelcox 的提示,参数initialValue 和callback 已经改变了它们的位置。所以这里是正确版本的代码:

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")
});
于 2013-04-10T19:35:26.700 回答
4

使用 coffeescript 时,我喜欢使用单行语法,首先使用获取属性值数组,.mapBy('propertyName')然后使用简单的 coffeescript reduce

@get('users').mapBy('tweetsUnread').reduce (a, b) -> a + b
于 2014-06-17T09:49:04.903 回答