Javascript 余烬正在等待关系加载到具有余烬并发性的数组中
我试图根据模型对象的一个相关模型对模型对象数组进行排序 我有一个文档,其中有许多行项目,还有一个行项目位于位置。我想按行项目的位置对其进行排序。如果我有这样的东西:Javascript 余烬正在等待关系加载到具有余烬并发性的数组中,javascript,ember.js,ember-data,Javascript,Ember.js,Ember Data,我试图根据模型对象的一个相关模型对模型对象数组进行排序 我有一个文档,其中有许多行项目,还有一个行项目位于位置。我想按行项目的位置对其进行排序。如果我有这样的东西: let lineItems = [ { itemName: "One", location: { name: "Kitchen" } }, { itemName: "Two", location: { name: "Kitchen" } },
let lineItems = [
{
itemName: "One",
location: {
name: "Kitchen"
}
},
{
itemName: "Two",
location: {
name: "Kitchen"
}
},
{
itemName: "Three",
location: {
name: "Bathroom"
}
},
{
itemName: "Four",
location: {
name: "Bathroom"
}
},
{
itemName: "Five",
location: {
name: "Hall"
}
},
{
itemName: "Six",
location: {
name: "Hall"
}
}
];
我想谈谈:
let groupedLineItems = {
"Kitchen": [
{
itemName: "One",
location: "Kitchen"
},
{
itemName: "Two",
location: "Kitchen"
},
],
"Bathroom": [
{
itemName: "Three",
location: "Bathroom"
},
{
itemName: "Four",
location: "Bathroom"
},
],
"Hall": [
{
itemName: "Five",
location: "Hall"
},
{
itemName: "Six",
location: "Hall"
}
]
}
我已经知道了如何排序,但只有在所有关系加载之后。我不知道如何使用ember并发在对数据排序之前等待所有关系加载
这是我的控制器:
~/app/controllers/document.js
import Ember from 'ember';
import _ from 'underscore';
import { task } from 'ember-concurrency';
const { computed } = Ember;
export default Ember.Controller.extend({
init() {
this.get('myTask').perform();
},
myTask: task(function * () {
// Wait for locations to resolve.
let lineItems = this.get('model').get('lineItems');
yield this.get("secondTask").perform(lineItems);
let groupedLineItems = yield _.groupBy(lineItems.toArray(), (lineItem) => {
lineItem.get('location').then((location) => {
return location.get('name');
});
});
this.set("groupedLineItems2", Ember.Object.create(groupedLineItems));
}),
secondTask: task(function * (lineItems) {
yield lineItems.toArray().forEach((lineItem) => {
lineItem.get('location');
});
})
});
这是控制器上的WIP,不正确。在init上,第一个任务运行,但不等待为每个行项目加载位置。我试图让它加载第二个任务中的所有位置,但这显然不是正确的方法。因此,在init上,它将运行排序,但是u.groupBy的函数将返回undefined,因为此时位置未定义。然后,如果我在知道位置已加载(因为我在模板的其他位置使用它们)后再次手动运行任务(使用模板上的按钮),则可以正常工作
解决方案不必使用ember并发,它看起来是正确的工具,但我认为它也可以通过承诺来实现。好问题
我会这样做的
models/document.js
:
import Ember from 'ember';
import Model from "ember-data/model";
import attr from "ember-data/attr";
import { belongsTo, hasMany } from "ember-data/relationships";
export default Model.extend({
lineItems: hasMany('line-item'),
groupedLineItemsPromise: Ember.computed(function () {
return this
.get('lineItems')
.then(lineItems => {
const locations = Ember.RSVP.all(lineItems.map(item => item.get('location')))
return Ember.RSVP.hash({lineItems, locations})
})
.then(({lineItems}) => {
return lineItems.reduce((result, item) => {
const locationName = item.get('location.name')
result[locationName] = result[locationName] || []
result[locationName].pushObject(item)
return result
}, {})
})
}),
groupedLineItemsProxy: Ember.computed('groupedLineItemsPromise', function () {
return Ember
.Object
.extend(Ember.PromiseProxyMixin)
.create({
promise: this.get('groupedLineItemsPromise')
})
})
});
演示:
请注意,您并不真正需要ember并发性
。我使用良好的旧计算属性来实现结果
但问题是,这首先是错误的方法,ember并发
与否:
在最坏的情况下,仍然会执行大量请求,但在路由的模型钩子中执行,该钩子将负责异步并将记录(而不是承诺)馈送到控制器/模板中一旦相关记录被预加载,您就可以像同步一样访问关系这不是“排序”。谢谢,这是一个很好的答案!最后我意识到我需要这样做:
返回this.get('store').findRecord('document',params.document_id,{include:'lineItems.location'})代码>在我的模型钩子上的路线。然后我可以做:groupedLineItems:computed('model.lineItems.@each.location',function(){const lineItems=this.get('model').get('lineItems').toArray();返回这个.sortObject(u.groupBy(lineItems,(lineItem)=>lineItem.get('location').get('name');}