无法将Ember数据与JSONAPI和片段一起使用以支持嵌套的JSON数据

时间:2017-05-10 13:42:42

标签: serialization ember.js ember-data json-api

概述

我正在使用Ember数据并拥有JSONAPI。一切正常,直到我有一个更复杂的对象(让我们说一个通用概念的发票)与一个名为lineEntries的项目数组。行条目不直接映射到表,因此需要存储为原始JSON对象数据。行条目模型还包含默认值和计算值。我希望将列表数据存储为JSON对象,然后在从商店加载回来时,我可以在Ember中正常操作它作为我的模型数组。

我尝试了什么

我看过并尝试过几种方法,最好的方法似乎是(这里有建议!):

片段

用片段替换问题模型

我尝试将行条目模型设为片段,然后将发票模型上的片段作为fragmentArray引用。行条目正常添加到数组,但默认值不起作用(应该吗?)。它创建了对象,我可以将它存储在后端,但是当我返回它时,它会因规范化问题或序列化问题而失败。任何人都可以说明返回数据的格式吗?令人困惑的是,规范化数据似乎需要JSONAPI,但片段需要JSON序列化器。到目前为止,我尝试了几种组合但没有运气。我的行条目没有实际ID,因为数据被保存并作为块加载。这是一个问题吗?

DS.EmbeddedRecordsMixin

虽然JSONAPI不支持,但听起来可能会使用JSONAPI,然后切换到问题模型的JSONSerializer或RESTSerializer。如果这是可能的,有人可以给我一个工作示例和应该由API返回的JSON格式吗?我有头文件授权和其他此类数据,所以我仍然能够在应用程序级别为所有不使用我的JSONAPI的请求设置此项吗?

烬数据保存-关系

我在here上找到了一个添加内容,可以添加一些内容来执行此操作。它似乎比其他方法更复杂,但是当我尝试这个时,我可以通过将数据设置为嵌入来发送数据。大!但是,尽管它保存了它并没有解开正确的问题,但我回到了同样的问题。

自定义序列化程序

将模型序列化器替换为获取数据的内容并将其作为普通JSON数据发送,然后反序列化为Ember可以使用的内容。这听起来与上面类似,但我做的很重。这样做的唯一原因是因为上述解决方案的所有示例都非常简单,并且没有真正展示如何使用需要它的实际JSONAPI设置来设置它。

我在哪里以及我需要什么

基本上所有方法都可以保存JSON,但是从服务器返回的JSON不是正确的格式或反序列化失败但是不清楚它应该是什么或者需要改变什么而不破坏现有的JSONAPI模型。

如果有人知道返回API数据的格式,它可以解决此问题。我已尝试使用lineEntries返回与保存时相同格式的JSONAPI。我已经尝试过放置像建议添加的关系部分,我也尝试将关系数据放在条目和包含所有引用的包含部分。任何有关这方面的帮助都会很棒,因为我已经通过这方面学到了很多东西,但最后期限迫在眉睫,我无法看到一个可行的解决方案,它不会像修复那样破坏。

1 个答案:

答案 0 :(得分:1)

如果您正在寻找API服务器的关系数据的返回格式,您需要确保以下内容:

  1. 确保在ember模型中定义关系
  2. 返回状态代码为200
  3. 的所有成功案例

    从那里你需要确保正确返回关系数据。如果您将关系的ember模型设置为{async: true},则只需要返回关系模型的id - 它也应该在ember中定义。如果您未设置{async: true},则ember希望包含所有关系数据。

    1. 使用JSON API规范中的关系返回数据
    2. 实施例

      在ember中

      models\unicorn.js

      import DS from 'ember-data';
      
      export default DS.Model.extend({
        user: DS.belongsTo('user', {async: true}),
        staticrace: DS.belongsTo('staticrace',{async: true}),
        unicornName: DS.attr('string'),
        unicornLevel: DS.attr('number'),
        experience: DS.attr('number'),
        hatchesAt: DS.attr('number'),
        isHatched: DS.attr('boolean'),
        raceEndsAt: DS.attr('number'),
        isRacing: DS.attr('boolean'),
      });
      
      routes\unicorns.js上的api服务器上的GET/:id中的

      var jsonObject = {
        "data": {
          "type": "unicorn",
          "id": unicorn.dataValues.id,
          "attributes": {
            "unicorn-name" : unicorn.dataValues.unicornName,
            "unicorn-level" : unicorn.dataValues.unicornLevel,
            "experience" : unicorn.dataValues.experience,
            "hatches-at" : unicorn.dataValues.hatchesAt,
            "is-hatched" : unicorn.dataValues.isHatched,
            "raceEndsAt" : unicorn.dataValues.raceEndsAt,
            "isRacing" : unicorn.dataValues.isRacing
          },
          "relationships": {
            "staticrace": {
              "data": {"type": "staticrace", "id" : unicorn.dataValues.staticRaceId}
            },
            "user":{
              "data": {"type": "user", "id" : unicorn.dataValues.userId}
            }
          }
        }
      }
      res.status(200).json(jsonObject);
      

      在ember中,您可以通过链接模型函数来调用它。例如,当这只独角兽参加controllers\unicornracer.js

      比赛时
      raceUnicorn() {
        if (this.get('unicornId') === '') {return false}
        else {
        return this.store.findRecord('unicorn', this.get('unicornId', { backgroundReload: false})).then(unicorn => {
          return this.store.findRecord('staticrace', this.get('raceId')).then(staticrace => {
            if (unicorn.getProperties('unicornLevel').unicornLevel >= staticrace.getProperties('raceMinimumLevel').raceMinimumLevel) {
              unicorn.set('isRacing', true);
              unicorn.set('staticrace', staticrace);
              unicorn.set('raceEndsAt', Math.floor(Date.now()/1000) + staticrace.get('duration'))
              this.set('unicornId', '');
              return unicorn.save();
            }
            else {return false;}
          });
        });
        }
      }
      

      以上代码将PATCH发送到api服务器路由unicorns/:id

      关于GETPOSTDELETEPATCH的最终说明:

      GET假设您获得了与模型相关的所有信息(上面的示例显示了GET响应)。这与model.findRecord(GET /:id)(期望一条记录),model.findAll(GET /)(期望记录数组),model.query(GET /?query =& string =)相关联(期望)一个记录数组),model.queryRecord(GET /?query =& string =)(期望一条记录)

      POST假设您至少从ember中返回至少POST到api服务器的内容,但也可以返回您在apiServer端创建的其他信息,例如createdAt dates。如果返回的数据与您用于创建模型的数据不同,它将使用返回的信息更新创建的模型。这与model.createRecord(POST /)相关联(期望一条记录)。

      DELETE假设您返回已删除对象的类型和ID,而不是数据或关系。这与model.deleteRecord(DELETE /:id)相关联(期望一条记录)。

      PATCH假设您至少返回了更改的信息。如果您只更改一个字段,例如在我的unicorn模型unicornName中,则只会修改以下内容:

      {
        data: {
          "type":"unicorn",
          "id": req.params.id,
          "attributes": {
            "unicorn-name" : "This is a new name!"
          }
        }
      }
      

      所以它只需要至少返回的响应,但是像POST一样,你可以返回其他更改的项目!

      我希望这能回答您关于JSON API适配器的问题。大部分信息最初都是通过阅读http://jsonapi.org/format/上的规范以及https://emberjs.com/api/data/classes/DS.JSONAPIAdapter.html上的ember实施文档

      而发布的。