Ember.js:计算所有子模型
我的应用有以下型号的财产的总和:Ember.js:计算所有子模型
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')
});
如何计算所有App.User.tweetsUnread的总和,并使其自动更新应用程序.List.tweetsUnread?
下应该这样做。有可能是使用减少一个更简洁的解决方案,但我从来没有使用过它自己:-)
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和回调已经改变了它们的位置。所以这里的正确版本的代码:
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]")
});
当使用CoffeeScript的,我喜欢用一个行语法,首先得到的属性值阵列.mapBy('propertyName')
,然后用一个简单的CoffeeScript reduce
:
@get('users').mapBy('tweetsUnread').reduce (a, b) -> a + b
另一种选择是使用Ember.computed.sum
看到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')
});
这显然是最好的解决办法,所以我不知道为什么它不是在顶部.. – 2015-06-10 06:16:16
@ BlueRaja-DannyPflughoeft因为这么认为,被OP标记为最佳答案的答案应该在最上面! :( – Caltor 2017-11-21 15:53:17
谢谢,减少的伎俩(_edited有点添加ŧ他正确params_) – 2013-04-12 19:13:20
在最近版本的灰烬(至少作为〜1.1),初始值是用于减少方法中的第二个参数。回调是第一个。 http://emberjs.com/api/classes/Ember.Enumerable.html#method_reduce – joelcox 2013-11-14 11:05:51
THX此提示。我已经相应地更新了这篇文章。 – mavilein 2013-11-14 16:03:30