我使用ember.js一周,遇到了有关ember-data和ember.js的问题。我在名为User
的模型上有一个简单的1:N关系。 User
有多个Slots
,由start_time
和end_time
定义。
在名为slots-per-day
的组件中,给定用户的所有插槽都按日过滤,并使用以下js代码:
/* ... rest of component.js of slots-per-day ... */
filteredSlots: Ember.computed('user', function() {
let time = moment();
return this.get('user.slots').filter( (slot) => {
let left = moment(time).startOf('day');
let right = moment(time).endOf('day');
let start_time = moment(slot.get('start_time'));
let end_time = moment(slot.get('end_time'));
console.debug(slot.get('start_time'));
return start_time.isBetween(left, right) || end_time.isBetween(left, right);
});
})
/* ... rest of component.js of slots-per-day ... */
我遇到了不同方法的几个问题:
使用上面的代码filterSlots-property仅评估一次。底层存储处于未定义状态,因为console.debug
输出undefined
但插槽数量恰到好处。所以我猜ember-data已经为插槽加载了数组,但忘记了来加载其余的数据。如果我转换到同一路线,所有数据都会正确显示,console.debug
会返回不同的moment.js-dates。
如果我将user.slots
添加到该属性的依赖项列表中,则会评估两次。两次评估都会产生与(1)中相同的调试输出:undefined
。
如果我添加user.slots.@each.start_time
,则会评估该属性,该页面上的组件数乘以插槽数量(这非常慢)。尽管它很慢,但它可以正常工作并呈现数据。
所以问题是:如何在渲染组件之前预加载ember-data中的所有数据?
修改:
我也尝试过承诺:
/* SlotRoute ... */
setupController(controller, model){
this._super(controller, model);
controller.set('time', this.get('time'));
controller.set('users', model.users);
controller.set('timeScope', this.get('timeScope'));
},
users: Ember.computed('time', function() {
return this.store.query('user', {
slots: {
time: this.get('time').toString(),
timeScope: this.get('timeScope')
}
});
}),
model(params) {
return Ember.RSVP.hash({
users: this.get('users'),
slots: this.store.get('slots')
});
},
/* ... */
上述列表的位置(1),(2)和(3)没有变化。
答案 0 :(得分:0)
编号3是编写计算属性的正确方法,尤其是异步关系。您必须在某个地方支付价格,如果您想在转换期间支付它,您可以使用afterModel
假设您使用model
挂钩获取用户。如果它在其他地方加载,您也可以使用该特定路线的afterModel
/ beforeModel
。
路线
model(params){
return this.store.find('user', 1);
},
afterModel(model, transition){
return model.get('slots');
}
使用某种服务的路线
afterModel(model, transition){
return this.get('someservice.user.slots');
}