2013-04-10 11 views
14

私のアプリケーションは、次のモデルがあります:Ember.js:すべての子モデルのプロパティの合計を計算

私はすべてのApp.User.tweetsUnreadの合計を計算し、それが自動的にアプリを更新することができますどのように
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('[email protected]'), 
    list: DS.belongsTo('App.List') 
}); 

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

.List.tweetsUnread?

答えて

13

次のようにします。そこ減らす使用して、より簡潔な解決策になるかもしれませんが、私自身は

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("[email protected]") 
}); 

更新:-)それを使ったことがない:これは減らす使用して、よりエレガントな解決策である。私はそれを使ったことがないし、これはテストされていませんが、私は、これは動作するはずということはかなり確信しています:

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("[email protected]") 
}); 

エンバー1.1減らすためのAPIで変更されました! Thx @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("[email protected]") 
}); 
+0

感謝を参照してください使用トリックをやっ減らすことであろう(トンを追加するためのビットを_edited彼は正しいparams_) –

+2

最近のバージョンのEmber(少なくとも〜1.1まで)では、初期値はreduceメソッドの第2引数です。コールバックが最初です。 http://emberjs.com/api/classes/Ember.Enumerable.html#method_reduce – joelcox

+0

このヒントのThx。私はそれに応じて投稿を更新しました。 – mavilein

3

のCoffeeScriptを使用する場合は、私が最初に.mapBy('propertyName')とプロパティ値の配列を取得し、その後、簡単なCoffeeScriptのreduce使用して、1ラインの構文を使用したい:

@get('users').mapBy('tweetsUnread').reduce (a, b) -> a + b 
36

別のオプションは、Ember.computed.sumhere

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') 
}); 
+2

これは明らかに最適なソリューションですので、SOと信じているので、それは...最上部にBlueRaja-DannyPflughoeft @ –

+0

ではありませんなぜ私はわかりませんOPの最善の答えとしてフラグが立てられた答えが一番上になければなりません! :( – Caltor

関連する問題