Setting up a controller property after the model hook

醉酒当歌 提交于 2019-12-02 13:38:18

问题


I need to set a controller property after the model hook. I can think of two ways to do this:

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'));
},

The other approach. i.e. skip setupController:

model(params) {
  return this.store.findRecord('user', 1);
},

afterModel(model, transition) {
  model.get('profile').then(profile => {
    this.controller.set('profile', profile);
  });
},

Both seem to work.

Are there any added advantages / disadvantages with either approach? Clearly, the latter is shorter. But does it feel "clean" to set the controller property in an afterModel hook?

EDIT: the relationship/association between user and profile is async.


回答1:


As another poster pointed out, you can access model.profile, but that won't work from code if profile is an async association:

// models/user.js
profile: belongsTo('profile', { async: true })

The reason is that model.profile will return a promise rather than a value. To solve that, you can use the afterModel hook as you suggested, but all you need is

afterModel(model, transition) {
  return model.get('profile');
},

That will issue the async call and pause the transition until it is completed, at which point the profile may be accessed as model.profile as usual. If for some reason you really want to access the profile as a controller property to avoid having to prefix it with model., just define an alias in your controller:

profile: Ember.computed.alias('model.profile')  

If there is more than one such property, then the following should do the job:

return Ember.RSVP.Promise.hash(this.getProperties('profile', ...));

You could also implement this right in the model hook, although it's a bit less readable:

model() {
  return this.store.findRecord('user', 1) .
    then(user => user.get('profile') . 
      then(() => user)
    );
}

What this says is, find the user, and then when found get his profile (which will cause the async request to fire), then when that is found return the user from the promise, so it is correctly set into model.




回答2:


You don't need any of those code, because controller has access to model via this.model. In any controller's method you can just call this.get('model.profile'). In template you may use {{model.profile}}.



来源:https://stackoverflow.com/questions/32554068/setting-up-a-controller-property-after-the-model-hook

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!