Ember.js 试图理解承诺在余烬中是如何运作的

Ember.js 试图理解承诺在余烬中是如何运作的,ember.js,ember-cli,Ember.js,Ember Cli,当我想我终于掌握了承诺在余烬中如何运作的概念。这种情况使我又回到了混乱的轨道上 用户模型具有以下关联: profile: DS.belongsTo('polymorphable', { polymorphic: true, async: true }) 路线包括: model: function(params) { return this.store.findRecord('user', 1); } 在模板中,我正在渲染一个组件: {{model.profile.firstName}}

当我想我终于掌握了承诺在余烬中如何运作的概念。这种情况使我又回到了混乱的轨道上

用户模型具有以下关联:

profile: DS.belongsTo('polymorphable', { polymorphic: true, async: true })
路线包括:

model: function(params) {
  return this.store.findRecord('user', 1);
}
在模板中,我正在渲染一个组件:

{{model.profile.firstName}}
{{foo-bar saveProfile=(action "save") profile=model.profile}}
{{model.profile.firstName}}
渲染良好

组件模板具有:

<button {{action "saveProfile" profile}}>Save</button>
单击组件模板中的按钮时<代码>控制台.日志呈现:

Class {isFulfilled: true, __nextSuper: undefined, __ember_meta__: Object, __ember1442167214792: "ember688"}

模板已解析
model.profile
,它正在将解析值传递给模板。为什么
profile
(在组件中)返回一个承诺?

我想猜一下,因为您没有包含
用户
类定义。配置文件属性是异步关系,异步关系使用代理承诺

代理承诺允许您在代理承诺上使用getter,它将解析属性,就像它存在于代理本身一样。这意味着您的模板没有解析的
配置文件
,而是调用
model.get('profile.firstName')
,并获取解析的值(即使以后满足了配置文件)

model.profile
作为代理承诺,当承诺已经实现时,您可以对其使用getter,并期望显示底层记录中的值

由于关系是异步的,所以您应该始终假定它尚未实现,并在尝试使用记录之前等待承诺的实现

actions: {
  saveProfile(profilePromise) {
    profilePromise.then(function(profileRecord){
      console.log(profileRecord);
    });
  }
}
使用铸件
如果我在不同的路径中使用相同的组件,但这次我直接传递
概要文件
对象(而不是用户),该怎么办。
saveProfile
应该是什么样子?在您的示例中,
saveProfile
期望传入的参数是一个promise对象。我个人认为解决promise不应该是组件的工作,尽管使用rsvp cast实现它非常容易。简单地把它变成一个承诺,如果它是一个承诺,什么都不会改变,如果它不是,它会把它包装成一个承诺。(上面举了一个例子)如果你想事先解决它,并将它连接到控制器上,然后正确地传递它,我会看看我对这个问题的回答,它应该能够引导你走上正确的道路:我也同意组件解决承诺会让你感觉脏兮兮的。我正在考虑使用
afterModel
hook来设置
profile
,然后在模板中,我可以通过以下方式呈现组件:
{{{foo bar saveProfile=(action“save”)profile=profile}
。你对此有何看法?或者有更好的方法吗?这是我会使用的方法,感觉正确的代码在做正确的事情。
actions: {
  saveProfile(profilePromise) {
    profilePromise.then(function(profileRecord){
      console.log(profileRecord);
    });
  }
}
actions: {
  saveProfile(profileMaybePromise) {
    Ember.RSVP.Promise.cast(profileMaybePromise).then(function(profileRecord){
      console.log(profileRecord);
    });
  }
}