问题 Ember-Data递归hasMany关联


有没有人用ember-data建模数据树?

我会假设它会是这样的:

Node = DS.Model.extend({
    children: DS.hasMany(Node),
    parent:   DS.belongsTo(Node)
});

然而,我无法得到这种工作,导致相信:1)我在如何设置这个问题上是完全错误的,或者2)目前无法使用ember对树进行建模-数据。

我希望它是前者,而不是后者......

当然它可能是JSON ......我假设JSON应该是这样的形式:

{
    nodes: [
        { id: 1, children_ids: [2,3], parent_id: null },
        { id: 2, children_ids: [], parent_id: 1 },
        { id: 3, children_ids: [], parent_id: 1 }
    ]
}

任何有关此问题的提示/建议将不胜感激。


8098
2017-08-16 23:54


起源

什么不能正常工作?你能否在你的问题中添加一些代码来向我们展示问题? - Stéphane Blond
当然,我设置了一个简单的 jsFiddle示例 这表明我认为我应该定义模型,然后搜索根节点并尝试访问子节点(这是事情发生的地方)。 - Heuristocrat
这是一个有用的小提琴。我在非递归的hasMany中遇到过类似的问题,所以我很想看到任何解决方案。 - pjmorse


答案:


有几件小事阻止你的小提琴工作:

  • DS.hasMany function要求String作为参数。不要忘记引号: DS.hasMany('Node')

  • 在夹具定义中, hasMany 关系不应该被后缀 _ids 什么的只需使用普通名称即可。例如: { id: 42, children: [2,3], parent_id: 17 }

  • length 的财产 DS.ManyArray 应该使用。访问 get 功能: root.get('children.length')

  • 默认情况下,fixture适配器模拟ajax调用。该 find 查询将在等待50ms后填充记录。在你的小提琴, root.get('children.length') 打电话来得太早了。您可以配置夹具适配器,以便进行同步调用:

    App.store = DS.Store.create({
        revision: 4,
        adapter: DS.FixtureAdapter.create({
            simulateRemoteResponse: false
        })
    });
    

    或者,您可以在没有任何适配器的情

    App.store.loadMany(App.Node, [
        { id: 1, children: [2, 3] },
        { id: 2, children: [], parent_id: 1 },
        { id: 3, children: [], parent_id: 1 }
    ]);
    
  • 最后一个:似乎应该在全球范围内声明Ember应用程序(没有 var),应在应用范围内声明Ember数据模型(替换 var Node = ... 通过 App.Node = ...

完整示例:

App = Ember.Application.create();

App.store = DS.Store.create({
    revision: 4
});

App.Node = DS.Model.extend({
    children: DS.hasMany('App.Node'),
    parent:   DS.belongsTo('App.Node')
});

App.store.loadMany(App.Node, [
    { id: 1, children: [2, 3] },
    { id: 2, children: [], parent_id: 1 },
    { id: 3, children: [], parent_id: 1 }
]);

var root = App.store.find(App.Node, 1);

alert(root.get('children'));
alert(root.get('children.length'));

14
2017-08-21 08:16



假设App.Node具有属性“name”,是否可以迭代模板中的所有子项:{{#controller child in controller.children}} {{child.name}} {{/ each}}? - lipp
如何在不遇到无限递归的情况下删除节点?我目前正面临这个问题。 - Tim O


在我设置反向之前,这对我不起作用:

App.Node = DS.Model.extend({
    children: DS.hasMany('App.Node', {inverse: 'parent'}),
    parent:   DS.belongsTo('App.Node', {inverse: 'children'}) });

1
2017-08-23 16:03



它似乎不适用于ember-data 1.0.0-beta.7(最新版本)。有没有人在最新版本中解决这个问题? - Gorzas


不确定但是按照ember指南中给出的例子

App.Post = DS.Model.extend({
  comments: DS.hasMany('App.Comment')
});

JSON应该将关系编码为ID数组:

{
  "post": {
    "comment_ids": [1, 2, 3]
  }
}

-3
2018-03-07 06:30