我正在处理一堆记录,并为第三方库生成一系列哈希。对于我的一生,我不知道为什么这行不通。
export default Route.extend({
model: function(params) {
let qp = {viewName: 'byDay'};
return this.store.query('job-receipt', qp).then(
(receipts)=>
all(
receipts.map(
(receipt)=>
hash({
stockCode: receipt.get('job')
.then(job => job.get('stockCode'))
.then(stockCode => stockCode.get('stockCode')),
productClass: receipt.get('job')
.then(job => job.get('stockCode'))
.then(stockCode => stockCode.get('productClass'))
.then(productClass => productClass.get('descr')),
qtyRecvd: receipt.get('qtyRecvd')
})
)
)
);
如果我继续重新进入路线,最终诺言就会解决。如果我检查,productClass承诺会直接使用null值调用。为什么不等待stockCode.get('productClass')解析?我知道其中确实存在价值,因为它最终会解决。
我缺少一些超级基础的东西。我已经尝试过Ember.get(thing,keypath)等。难道这些都不都能兑现承诺吗? RSVP.hash是否不应该等待所有的诺言才能解决,然后再继续?就像我说的那样,我知道数据很好,因为最终数据确实可以解析(与之相对,我只是不处理拒绝)。
编辑:
我将productClass的承诺更改为:
productClass: receipt.get('job')
.then(job => job.get('stockCode'))
.then(stockCode => stockCode.get('productClass'))
.then(productClass => {if (!productClass) {return 'foo';} return productClass.get('descr');})
现在,尽管每次都毫无意义,但报表仍可以正确呈现。如果我导航到另一条路线,然后返回到该路线,则它会完美呈现。因此,这使我很难相信自己有某种数据错误。甚至某些股票代码在首次运行时都返回正确的产品类别-而不是'foo'。我什至不知道如何进一步调试它。
修改
刚刚看到了这个。毕竟可能是一个错误。
答案 0 :(得分:2)
事实证明这是一个错误。属于-to.js的错误导致模型在解决承诺之前不等待internalModel完成加载。下面链接的修复程序解决了问题
答案 1 :(得分:1)
我认为主要问题是“ reciepts.job”可能是DS.belongsTo关系,对吗?如果将其切换为加载job: DS.belongsTo('job', {async: false})
,则将强制ember-data同步加载该属性(并节省很多麻烦)。但这要求数据在json响应中都可用。
如果这不起作用,则应调查ember concurrency。使用它来清理您的代码,使其看起来更加简单。在我误解了您的用例的地方,您必须填写一些空白或进行更改,但这可能是一个不错的起点。
想法是继续将所有异步调用分解为单独的任务。每个ember-concurrency task
对象都返回一个诺言,因此您可以将它们捆绑在一起,直到到达model
为止,您可以像其他任何诺言一样返回。
//model.js
import {task} from 'ember-concurrency';
.....
model() {
return this.get('loadData').perform();
},
loadData: task(function*(){
let reciepts = yield this.store.query('job-receipt', qp);
let promises = reciepts.map(r => {
return this.get('loadNestedData').perform(r);
})
return all(promises)
}),
loadNestedData: task(function*(reciept) {
let job = yield receipt.get('job');
return hash({
stockCode: job.get('sockcode')
});
})