javascript - Ember-data:加载一对一相关模型

标签 javascript ember.js ember-data

我觉得我错过了一些非常简单的东西。我创建了两个相互关联的模型,每个模型都具有 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 Data 期望 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
        },
    ],
}

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

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

{
    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 Data)大量使用 promises,实现这一点的一种方法是链接 promises(“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

关于javascript - Ember-data:加载一对一相关模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28512574/

相关文章:

ember.js - Emberjs 表单、提交函数和操作帮助程序错误

javascript - store.push 没有反射(reflect)在带有 ember-cli-pagination 的模板上

ember.js - 如何找到 Ember-Data、Ember-CLI 和 Ember.js 的最新发布版本?

javascript - EmberJS - 具有 hasMany 关系的记录无法加载

javascript - 为什么函数不能访问外部声明的对象中的局部变量

javascript - 查找和替换 double “NON BREAKING SPACE” 的正则表达式

javascript - Ember - 将数据从服务器检索到 View ?

javascript - 我需要一个 javascript 递归函数,当 key 和 json 对象传递给这个函数时,它返回一个值数组

foreach : need help creating a closure 中的 Javascript setTimeout

ember.js - 仪表板的最佳实践