【问题标题】:How to make embedded hasMany relationships work with ember data如何使嵌入的 hasMany 关系与 ember 数据一起使用
【发布时间】:2012-12-28 13:25:25
【问题描述】:

我无法让 embedded hasMany 正确处理 ember 数据。

我有这样的事情

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

App.Comment = DS.Model.extend({
  post: DS.hasMany('App.Post'),
  name: attr('string')
});

我的 API 为 GET /post 返回以下内容:

[
  {
   id: 1
   comments: [{name: 'test'}, {name: 'test2'}]
  },
  ...
]

我需要用POST /post发送这个:

[
  {
    comments: [{name: 'test'}, {name: 'test2'}]
  },
  ...
]

我想使用 Ember 模型并让他们提出适当的请求:

var post = App.store.createRecord(App.Post, hash_post_without_comments);
post.get('comments').createRecord(hash_comment);

App.store.commit(); // This should call the POST api 

var posts = App.store.find(App.Post); // This should call the GET api 

当我尝试post: DS.hasMany('App.Post', {embedded: true}) 之类的方法时,GET 正在工作,但 POST 正在尝试为这两条记录创建一个 POST,而不仅仅是父记录。

编辑:我的真实用例

1- 我刚刚从 master 构建了 ember 数据

2- 我的适配器:RESTAdapter

3- 序列化器:JSONSerializer

4- 我添加了

App.MyAdapter.map('App.Join', {
    columns: { embedded: 'always' }
});

5- 我的模型是:

App.Join = DS.Model.extend({
    rowCount: DS.attr('number'),
    columns: DS.hasMany('App.JoinColumn'),
});

App.JoinColumn = DS.Model.extend({
    join: DS.belongsTo('App.Join')
});

6- 时间:

var a = App.Join.find(1);
a.get('columns').createRecord({});
App.store.commit();

连接列的 POST 已发送且父级不脏

我错过了什么?

【问题讨论】:

标签: javascript ember.js ember-data


【解决方案1】:

这对我有用(Ember 1.5.1+pre.5349ffcb,Ember Data 1.0.0-beta.7.f87cba88):

App.Post = DS.Model.extend({
  comments: DS.hasMany('comment', { embedded: 'always' })
});

App.PostSerializer = DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {
  attrs: {
    comments: { embedded: 'always' }
  }
});

【讨论】:

    【解决方案2】:

    为此添加更新,以防其他人看到此帖子并且很难弄清楚当前版本的 ember-data 的适用范围。

    从 Ember Data 1.0.0.beta.7 开始,您需要覆盖序列化程序上的相应方法。这是一个例子:

    1) 重新打开序列化程序(感谢this post):

    DS.RESTSerializer.reopen({
      serializeHasMany: function(record, json, relationship) {
        var hasManyRecords, key;
        key = relationship.key;
        hasManyRecords = Ember.get(record, key);
        if (hasManyRecords && relationship.options.embedded === "always") {
          json[key] = [];
          hasManyRecords.forEach(function(item, index) {
            // use includeId: true if you want the id of each model on the hasMany relationship
            json[key].push(item.serialize({ includeId: true }));
          });
        } else {
          this._super(record, json, relationship);
        }
      }
    });
    

    2) 将embedded: 'always' 选项添加到模型上的关系中:

    App.Post = DS.Model.extend({
      comments: DS.hasMany('comment', {
        embedded: 'always'
      })
    });
    

    【讨论】:

      【解决方案3】:

      在 master 上,正确的 API 是:

      App.Adapter.map('App.Post', {
        comments: { embedded: 'always' }
      });
      

      embedded 的两个可能值是:

      • load:加载时嵌入子记录,但应保存为独立记录。为此,子记录必须有一个 ID。
      • always:子记录在加载时嵌入,并保存嵌入在同一记录中。这当然会影响记录的脏度(如果子记录发生更改,适配器会将父记录标记为脏)。

      如果没有自定义适配器,可以直接在DS.RESTAdapter上调用map

      DS.RESTAdapter.map('App.Post', {
        comments: { embedded: 'always' }
      });
      

      【讨论】:

      • belongsTo 也一样吗?
      • 是的。它与嵌入式 belongsTo 的 API 相同。
      • 我认为持久化嵌入记录时可能存在错误,github.com/emberjs/data/pull/578
      • @YehudaKatz,随着对 ember-data 的新修订,通过自定义适配器映射的正确方法是什么? Adapter.map 函数不再存在。
      • 我认为,我们必须遵循这个 JSON 约定。嵌入对象跟随主要对象。 emberjs.com/guides/models/connecting-to-an-http-server/…
      【解决方案4】:

      我也有同样的问题。

      此错误已在 ember 数据问题跟踪器上报告。 以下 PR 添加了 2 个失败的测试来显示问题:https://github.com/emberjs/data/pull/578

      目前似乎没有解决方法。

      编辑:

      sebastianseilund 2 天前打开了一个 PR,它解决了您的问题。 看看:https://github.com/emberjs/data/pull/629/files

      【讨论】:

        猜你喜欢
        • 2015-02-21
        • 2015-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-04
        • 2014-09-27
        • 1970-01-01
        相关资源
        最近更新 更多