Javascript非常新,甚至更新到Ember,我有一个异步hasMany关联,我试图在父模型控制器中对子模型(锦标赛)上的属性求和。我对函数范围的理解是内部函数可以访问包含函数中的所有内容(除此之外),并且到现在为止一直很好。我试图在承诺结算时添加金额,但它必须是一个新的金额变量,因为我一旦回到外面,它就会回到0,我就会变成0。我不知道我哪里出错了。我知道我没有在.property()中设置依赖项,我只是想先对它进行排序。
totalPrice: function(){
var self = this;
var allTourn = this.get('model.tournaments');
var amount = 0;
allTourn.forEach(function(tournament){
var tID = Number(tournament.get('id'));
self.store.find('tournament', tID).then(function(value){
amount += Number(value.get('buyIn'));
//amount is set to the buyIn property as expected
})
// amount is 0 out here... shouldnt the amount in the promise be using the outter amount variable?
});
return amount; // == 0
}.property()
基于Tony回答的解决方案 我把它移到路线上,并在视图中解决了承诺 路由/ package.js
export default Ember.Route.extend({
model: function(params) {
return this.store.find('package', params.package_id);
},
setupController: function(controller, model){
var allTourn = model.get('tournaments');
var self = this;
var totalPricePromise = new Ember.RSVP.Promise(function(resolve, reject) {
var tournyPromises = allTourn.map( function(tournament){
var tID = Number(tournament.get('id'));
return self.store.find('tournament', tID)
});
Ember.RSVP.all(tournyPromises).then(function(tournamentList){
var amount = 0;
tournamentList.forEach(function(tournament){
amount += Number(tournament.get('buyIn'));
})
resolve(amount);
controller.set('totalPrice', amount);
});
});
controller.set('package', model);
}
});
答案 0 :(得分:1)
就像评论中的eggward所说,totalPrice正在返回金额而不等待store.find()承诺。承诺排队等待以后运行,在totalPrice完成后的某个时间。
因此,如果您必须等待promises进行计算,那么您可以从totalPrice返回一个promise,并在所有store.find()调用完成时解析它。你可以使用Ember承诺'用于对查找进行分组的all()方法。例如,您可以尝试使用以下内容代替allTourn.forEach:
// create a promise to return from totalPrice()
var totalPricePromise = new Ember.RSVP.Promise(function(resolve, reject) {
// create an array of promises from the find() calls.
var tournyPromises = allTourn.map( function(tournament){
var tID = Number(tournament.get('id'));
return self.store.find('tournament', tID)
});
// user RSVP.all to wait for all the finds to complete
// it automatically groups all the results into an array
Ember.RSVP.all(tournyPromises).then(function(tournamentList){
var amount = 0;
tournamentList.forEach(tournament){
amount += Number(tournament.get('buyIn'));
})
// this resolve is from the Ember.RSVP.Promise at the top
// it will finally get to whoever called totalPrice()
resolve(amount);
});
// return the promise from totalPrice, instead of the amount
return totalPricePromise;
});
但是承诺可能不适合作为财产,例如,你需要一个把手帮手。作为替代方案,您可以将所有承诺内容移动到您设置模型的路线,以便在控制器中您已经拥有所有锦标赛。然后你不必在totalPrice函数中等待find()操作。