Model Ember.js:计算所有子模型的属性之和
我的应用程序具有以下型号:Model Ember.js:计算所有子模型的属性之和,model,ember.js,Model,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(){ ///////////////////
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?以下内容应该可以做到。使用reduce可能有一个更简洁的解决方案,但我自己从未使用过:-) 更新:这是一个使用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已更改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("users.@each.tweetsUnread")
});
使用coffeescript时,我喜欢使用单行语法,首先使用
.mapBy('propertyName')
获取属性值数组,然后使用简单的coffeescriptreduce
:
@get('users').mapBy('tweetsUnread').reduce (a, b) -> a + b
另一个选项是使用
Ember.computed.sum
参见
谢谢,reduce在Ember的最新版本(至少从~1.1开始)中完成了这个技巧(编辑了一点以添加正确的参数),初始值是reduce方法的第二个参数。回调是第一个。为什么reduce优于+=?不仅仅是好奇。使用reduce是遵循一种更实用的风格,在这种风格中,您试图避免副作用(例如作业)。使用+=您必须检查循环实际在做什么。Reduce已经暗示了一个特定的操作,您只需要对关闭进行推理。但我不想在这里开始讨论函数式编程与命令式编程:)@BlueRaja DannyPflughoeft,因为SO认为OP标记为最佳答案的答案应该在顶部!:(
@get('users').mapBy('tweetsUnread').reduce (a, b) -> a + b
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')
});