【问题标题】:How can I peek the contents of a hasMany relationship?如何查看 hasMany 关系的内容?
【发布时间】:2023-04-01 02:23:01
【问题描述】:

我有一个模特,Node:

App.Node = DS.Model.extend({
    parents: DS.hasMany('node', { inverse: null })
});

假设我的服务器正在发回部分树:

{ id: "A", parents: [ "C" ] }
{ id: "B", parents: [ "C", "D" ] }
{ id: "C", parents: [ "E" ] }

我想这样渲染:

A ---- C
      /
B ---/

但是,当我拨打B.get('parents') 时,我收到一条消息:

未捕获的错误:断言失败:您在 ID 为 B 的“节点”上查找了“父级”关系,但未加载一些相关记录。要么确保它们都与父记录一起加载,要么指定关系是异步的 (DS.hasMany({ async: true }))

这些都不适合我。我只想要图中加载的记录。

我可能最终也想渲染这样的东西:

A ---- C--?
      /
B ---/--?

用 UI 元素表示不重要的父母。

有没有办法只查看关系中加载的记录?

【问题讨论】:

    标签: ember.js ember-data


    【解决方案1】:

    好问题。

    目前,Ember Data 无法满足此类用例。

    您的问题有 an answer,但现在已过时:API 已更改,现在是私有的。

    如果你足够勇敢,你可以这样做:

    App.Node = DS.Model.extend({
      parent:   DS.belongsTo('node', {inverse: 'children'}),
      children: DS.hasMany('node', {inverse: 'parent'}),
    
      childrenIds: Ember.computed(
        '_internalModel._relationships.initializedRelationships.children.canonicalState.@each.ids',
        function() {
          var children =
            this
              ._internalModel
              ._relationships
              .initializedRelationships
              .children;
    
          if (!children) return [];
    
          return children
            .canonicalState
            .mapBy('id');
        }
      ),
    
      availableChildren: Ember.computed('childrenIds', function () {
        var childrenIds = this.get('childrenIds');
        return this.store.all('node').filter(function(node) {
          return childrenIds.indexOf(node.id) > -1;
        });
      })
    });
    

    演示:http://emberjs.jsbin.com/qugofu/1/edit?html,js,output

    这段代码的问题(除了使用私有 API)是availableChildren 属性在从服务器获取新节点时不会自动更新。

    你必须想办法做到这一点。完成后,将其作为插件发布!

    更新于 2015 年 7 月 20 日

    这个问题让我睡不着。

    我已经设法改进了上述解决方案:

    1. 它现在会在商店中出现新记录时自动更新。
    2. 它还会在记录关系发生变化时更新。

    缺点是对可用节点的查找发生在组件中,而不是在模型中。

    演示:http://emberjs.jsbin.com/qugofu/2/edit?html,js,output

    【讨论】:

    • 我钦佩您的聪明才智,但归根结底,这并不是一个真正可靠的解决方案。
    • 确实不是!另一方面,它仅依赖于单一的私有 API 使用。
    【解决方案2】:

    正如另一个答案正确指出的那样,Ember Data 很难处理这个问题。一个相关的情况是试图在不引发网络请求的情况下找到异步hasMany 关系的长度(计数)。问题在于 parents 属性本质上是一个承诺数组,它必须是对 something 的承诺。

    除非您想深入研究 Ember Data 内部结构,否则我会通过放弃 hasMany 并简单地将字段定义为 ID 数组来解决此问题。然后,当您确实需要父对象时,请执行find 来获取它们。您可以在适配器中使用coalesceFindRequests 以确保Ember 只进行一次网络调用来获取父母双方(如果您的服务器可以处理api/nodes?ids[]=A&ids[]=B 格式)。

    如果您愿意,可以将此行为封装到序列化程序和模型上的 mixin 中。

    【讨论】:

      【解决方案3】:

      目前(2016-07-03)这可以通过DS.Model's hasMany() method完成:

      var children = model.hasMany('children').value();
      

      【讨论】:

      • 对于后代,这需要 Ember-Data 2.5.0,但对于那些最新的人来说就像一个魅力。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-09
      • 1970-01-01
      • 1970-01-01
      • 2019-01-15
      • 1970-01-01
      • 1970-01-01
      • 2015-12-22
      相关资源
      最近更新 更多