Ember.js 在模型挂钩之后设置控制器属性
我需要在Ember.js 在模型挂钩之后设置控制器属性,ember.js,ember-data,ember-cli,Ember.js,Ember Data,Ember Cli,我需要在modelhook之后设置控制器属性。我可以想出两种方法: model(params) { return this.store.findRecord('user', 1); }, afterModel(model, transition) { model.get('profile').then(profile => { this.set('profile', profile); }); }, setupController(controller, model
model
hook之后设置控制器属性。我可以想出两种方法:
model(params) {
return this.store.findRecord('user', 1);
},
afterModel(model, transition) {
model.get('profile').then(profile => {
this.set('profile', profile);
});
},
setupController(controller, model) {
controller.set('model', model);
controller.set('profile', this.get('profile'));
},
另一种方法。i、 e.跳过设置控制器:
model(params) {
return this.store.findRecord('user', 1);
},
afterModel(model, transition) {
model.get('profile').then(profile => {
this.controller.set('profile', profile);
});
},
两者似乎都有效
这两种方法是否都有其他优点/缺点?显然,后者较短。但是在afterModel
hook中设置控制器属性是否感觉“干净”
编辑:
用户
和配置文件
之间的关系/关联是异步
您不需要这些代码,因为控制器可以通过此.model
访问模型。在任何控制器的方法中,您都可以调用this.get('model.profile')
。在模板中,您可以使用{{model.profile}
您不需要这些代码,因为控制器可以通过此.model
访问模型。在任何控制器的方法中,您都可以调用this.get('model.profile')
。在模板中,您可以使用{{{model.profile}
,正如另一张海报所指出的,您可以访问model.profile
,但如果profile
是异步关联,则无法使用代码:
// models/user.js
profile: belongsTo('profile', { async: true })
原因是model.profile
将返回承诺而不是值。要解决这个问题,您可以按照建议使用afterModel
hook,但您只需要
afterModel(model, transition) {
return model.get('profile');
},
这将发出异步调用并暂停转换,直到转换完成,此时可以像往常一样访问model.profile
。如果出于某种原因,您确实希望将配置文件作为控制器属性访问,以避免使用model.
作为前缀,只需在控制器中定义一个别名:
profile: Ember.computed.alias('model.profile')
如果存在多个此类财产,则应执行以下操作:
return Ember.RSVP.Promise.hash(this.getProperties('profile', ...));
您也可以在模型
钩子中实现这一权利,尽管它的可读性稍差:
model() {
return this.store.findRecord('user', 1) .
then(user => user.get('profile') .
then(() => user)
);
}
这意味着,找到用户,然后在找到时获取他的配置文件(这将导致异步请求触发),然后在找到该配置文件时从承诺中返回用户,因此它被正确设置为
model
,正如另一张海报所指出的,您可以访问model.profile
,但如果profile
是一个异步关联,那么这在代码中不起作用:
// models/user.js
profile: belongsTo('profile', { async: true })
原因是model.profile
将返回承诺而不是值。要解决这个问题,您可以按照建议使用afterModel
hook,但您只需要
afterModel(model, transition) {
return model.get('profile');
},
这将发出异步调用并暂停转换,直到转换完成,此时可以像往常一样访问model.profile
。如果出于某种原因,您确实希望将配置文件作为控制器属性访问,以避免使用model.
作为前缀,只需在控制器中定义一个别名:
profile: Ember.computed.alias('model.profile')
如果存在多个此类财产,则应执行以下操作:
return Ember.RSVP.Promise.hash(this.getProperties('profile', ...));
您也可以在模型
钩子中实现这一权利,尽管它的可读性稍差:
model() {
return this.store.findRecord('user', 1) .
then(user => user.get('profile') .
then(() => user)
);
}
这意味着,找到用户,然后在找到时获取他的配置文件(这将导致异步请求触发),然后在找到时从承诺中返回用户,因此它被正确设置为
model
调用this.get('model.profile')如果profile
是一个异步关联,则将不会达到预期效果。如果profile
是一个异步关联,则调用this.get('model.profile')
将不会达到预期效果。是的,关系是异步的。只需在afterModel
hook中执行model.get('profile')
,仍然会返回一个承诺。需要一个then
子句。还是我遗漏了什么?model.get('profile')
将发出异步请求,并返回一个承诺,告诉转换机制等待它完成。完成后,model.profile
将自动解析,以便将来对它的引用将返回该值model.profile
是一种混合的promise+value对象。哦,很有趣。刚刚试过这个,现在我明白了。我很好奇。只有当afterModel
钩子返回一个对象时,这才起作用。如果afterModel
钩子需要返回多个。i、 e.model.get('profile')
,和model.get('somethingElse')
。然后我是否应该使用this.controller.set
?您可以返回Ember.RSVP.Promise.all([this.get('profile'),…])
。或者可能返回Ember.RSVP.Promise.hash(this.getProperties('profile',…)代码>.Yeap,关系是异步的。只需在afterModel
hook中执行model.get('profile')
,仍然会返回一个承诺。需要一个then
子句。还是我遗漏了什么?model.get('profile')
将发出异步请求,并返回一个承诺,告诉转换机制等待它完成。完成后,model.profile
将自动解析,以便将来对它的引用将返回该值model.profile
是一种混合的promise+value对象。哦,很有趣。刚刚试过这个,现在我明白了。我很好奇。只有当afterModel
钩子返回一个对象时,这才起作用。如果afterModel
钩子需要返回多个。i、 e.model.get('profile')
,和model.get('somethingElse')
。然后我是否应该使用this.controller.set
?您可以返回Ember.RSVP.Promise.all([this.get('profile'),…])
。或者可能返回Ember.RSVP.Promise.hash(this.getProperties('profile',…)代码>。