【问题标题】:get length of hasMany relationship without triggering fetch在不触发 fetch 的情况下获取 hasMany 关系的长度
【发布时间】:2015-07-11 11:49:36
【问题描述】:

型号:

DS.Model.extend({
  title: DS.attr('string'),
  body: DS.attr('string'),
  comments: DS.hasMany('comment', { async: true} ),

  hasComments: Ember.computed.gt('comments.length', 0)
});

有效载荷:

{ 
  "id": "abcdefg",
  "title": "some cats are cool",
  "body": "",
  "comments: ["100", "101", "102"]
}

hasComments 计算属性会单独触发对每个评论的提取。我不想要这个:D

我知道这行得通(避免获取),但进入私有 API:

hasComments: Ember.computed.gt('data.comments.length', 0)

ember.js 1.8.1

ember-data 1.0.0-beta.11

关于根据长度实现计算属性的任何其他建议

【问题讨论】:

标签: ember.js ember-data


【解决方案1】:

从 Ember Data 2.5 (mentioned in release notes) 开始,有一个名为 ds-references 的功能提供了一种方法来检查 hasMany 关系是否包含项目而不触发对这些项目的获取:

export default Model.extend({
  title: DS.attr('string'),
  body: DS.attr('string'),
  comments: DS.hasMany('comment', { async: true} ),

  hasComments: Ember.computed('comments', function() {
    return this.hasMany('comments').ids().length > 0;
  })
});

看到这个工作in an Ember Twiddle

ds-references 功能实现了所描述的引用 API 在 RFC 57 中。References 是一个低级 API,用于执行元操作 记录、has-many 关系和 belongs-to 关系:

  • 同步获取当前本地数据,无需触发 fetch 或产生 Promise
  • 通知商店已开始获取给定记录,并为其结果提供承诺
  • 类似地,通知记录已开始获取给定关系,并为其结果提供承诺
  • 检索服务器提供的有关记录或关系的元数据

来源:Ember forum postEmber Data 2.5 release blog post

【讨论】:

    【解决方案2】:

    您提到,每条评论都是单独获取的。如果您的后端支持,可以通过在 RestAdapter 上设置 coalesceFindRequests 来避免这种情况。

    但是,您仍然有太多的请求。我不认为,如果没有某种肮脏的技巧就可以避免这种情况,但我愿意从其他答案中学习。

    【讨论】:

    • 感谢分享这个技巧。原来在 github 上有一个未解决的问题。通过直接链接为我的问题添加了评论。
    【解决方案3】:

    我希望有一个简单的方法来做到这一点。我能想到的最简单的方法是在您的序列化程序中覆盖extractHasMany 并在您的模型上保存一个新属性commentsCount,例如:

    模型/post.rb:

    DS.Model.extend({
      title: DS.attr('string'),
      body: DS.attr('string'),
      comments: DS.hasMany('comment', { async: true} ),
      commentsCount: DS.attr('number'),
    
      hasComments: Ember.computed.gt('commentsCount', 0)
    });
    

    序列化器/post.rb:

    export default ApplicationSerializer.extend({
      normalizeHash: {
        posts(hash) {
          hash.comments_count = hash.comments.length;
          return hash;
        }
      }
    }
    

    但要小心,因为在这种情况下,当您添加/删除 cmets 时 cmetsCount 属性不会自动重新计算。如果已加载 cmets,您可能会构建一个使用实际 cmets 而不是 commentsCount 的计算属性。

    【讨论】:

    猜你喜欢
    • 2023-03-12
    • 2021-02-26
    • 2023-03-31
    • 2014-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-02
    • 1970-01-01
    相关资源
    最近更新 更多