Ember-data:加载一对一关联模型

Ember-data: loading one-to-one related model

我觉得我错过了一些非常简单的东西。我创建了两个相互关联的模型,每个模型都具有 belongsTo('theOtherOne').

我有一个加载特定条目的路由:

入门型号

export default DS.Model.extend({
  word: DS.attr('string'),
  entry: DS.attr('number'),
  definition: DS.belongsTo('definition', {async: true}),
});

定义模型

export default DS.Model.extend({
  body: DS.attr(),
  entry: DS.belongsTo('entry')
});

路线

model: function(params){
    return this.store.find('Entry', params.entry_id);
}

那么,如何使相关记录可用于我的模板?我很确定关系配置正确,因为在 Ember 检查器中,我可以看到 "belongsTo" 属性 已设置,当我单击它时,适当的 API 调用并加载到商店中。但是,它仍然(显然)不可用于模板。

提前致谢。

可能的解决方案是从 Entry 模型的 Definition 属性 中删除 async: true 属性:

definition: DS.belongsTo('definition', {async: true}) // remove async: true

当 async 设置为 true 时,Ember 不会获取相关实体,直到您实际请求它们。设置为 false 时,Ember 将与请求的实体同时获取相关实体。

在您当前的 Entry 模型中:

word: DS.attr('string'),
entry: DS.attr('number'),
definition: DS.belongsTo('definition', {async: true}),

Ember 数据预计 Entry 请求仅 return 个条目。响应类似于:

{
    entries: [
        {
            id: "e1",
            word: "foo",
            entry: 1,
            definition: "d1" // id for definition belonging to this entry
        },   
        {
            id: "e2",
            word: "bar",
            entry: 2,
            definition: "d2" // id for definition belonging to this entry
        },
    ],
}

要获得实际定义,您需要发出第二个请求。

但是,如果您使关系同步,那么您将在单个请求中获得两个模型,响应如下:

{
    entries: [
        {
            id: "e1",
            word: "foo",
            entry: 1,
            definition: "d1" // id for definition belonging to this entry
        },   
        {
            id: "e2",
            word: "bar",
            entry: 2,
            definition: "d2" // id for definition belonging to this entry
        },
    ],
    definitions: [
        {
         id: "d1",
            body: "abc",
            entry: "e1"      // id for entry belonging to this definition
        },
        {
         id: "d2",
            body: "def",  
            entry: "e2"      // id for entry belonging to this definition
        }
    ]
    
}

编辑(根据您的评论)

由于两个模型处于不同的 API 点,您确实需要使这种关系异步并发出两个请求。由于 Ember(和 Ember 数据)大量使用承诺,实现此目的的一种方法是链接承诺 ("thenables"):

model: function() {
    var store = this.store;
    return store.find('entry').then(function() {  // success function, we got the entries so now we request definitions
        store.find('definition');
    }
}

如果此代码成功执行,条目和定义都将加载到商店中,并且您的路由模型将是条目数组。

注意 上面的代码没有正确的错误处理,只是展示了如何实现这一点的本质。

Here's a good read on JavaScript promises

Ember's documentation on promises