解析路由中的键路径(或链式关系)
Resolving keypaths (or chained relationships) in route
我正在处理一堆记录并为第三方库生成一个哈希数组。对于我的生活,我无法弄清楚为什么这不起作用。
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 promise 会直接被调用并返回一个空值。为什么不等待 stockCode.get('productClass') 解决?我知道那里有真正的价值,因为它最终会解决。
我缺少一些非常基本的东西。我试过 Ember.get(thing, keypath) 等。难道这些不是所有 return 的承诺吗?难道 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');})
现在报告每次都能正确呈现,尽管有一些废话。如果我导航到另一条路线,然后回到这条路线,它会完美呈现。所以,这让我很难相信我有某种数据错误。甚至有些股票代码return对产品class——不是'foo'——就先运行通过。我什至不确定如何进一步调试它。
编辑
刚看到这个。毕竟可能是一个错误。
我认为主要问题是 "reciepts.job" 很可能是 DS.belongsTo 关系,对吗?如果您将其切换为加载 job: DS.belongsTo('job', {async: false})
,那将强制 ember-data 同步加载 属性(并且会省去很多麻烦)。但这要求数据在 json 响应中可用。
如果这不起作用,您应该调查 ember concurrency。使用它来清理您的代码,使其看起来更直接一些。您必须填写一些空白或更改我误解了您的用例的内容,但这可能是一个很好的起点。
想法是继续将所有异步调用分解为单独的任务。每个 ember-并发 task
对象 return 都是一个承诺,因此您可以继续将它们捆绑在一起,直到达到 model
,您可以像其他任何对象一样 return承诺。
//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')
});
})
原来是个bug。 belongs-to.js 的错误导致模型在解决承诺之前不等待 internalModel 完成加载。下面链接的修复解决了这个问题
我正在处理一堆记录并为第三方库生成一个哈希数组。对于我的生活,我无法弄清楚为什么这不起作用。
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 promise 会直接被调用并返回一个空值。为什么不等待 stockCode.get('productClass') 解决?我知道那里有真正的价值,因为它最终会解决。
我缺少一些非常基本的东西。我试过 Ember.get(thing, keypath) 等。难道这些不是所有 return 的承诺吗?难道 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');})
现在报告每次都能正确呈现,尽管有一些废话。如果我导航到另一条路线,然后回到这条路线,它会完美呈现。所以,这让我很难相信我有某种数据错误。甚至有些股票代码return对产品class——不是'foo'——就先运行通过。我什至不确定如何进一步调试它。
编辑
刚看到这个。毕竟可能是一个错误。
我认为主要问题是 "reciepts.job" 很可能是 DS.belongsTo 关系,对吗?如果您将其切换为加载 job: DS.belongsTo('job', {async: false})
,那将强制 ember-data 同步加载 属性(并且会省去很多麻烦)。但这要求数据在 json 响应中可用。
如果这不起作用,您应该调查 ember concurrency。使用它来清理您的代码,使其看起来更直接一些。您必须填写一些空白或更改我误解了您的用例的内容,但这可能是一个很好的起点。
想法是继续将所有异步调用分解为单独的任务。每个 ember-并发 task
对象 return 都是一个承诺,因此您可以继续将它们捆绑在一起,直到达到 model
,您可以像其他任何对象一样 return承诺。
//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')
});
})
原来是个bug。 belongs-to.js 的错误导致模型在解决承诺之前不等待 internalModel 完成加载。下面链接的修复解决了这个问题