与数组

时间:2015-06-02 15:28:16

标签: ember.js ember-data ember-cli

我很难理解模型关系在ember-data中的工作原理。我理解一对多或一对一或多对多的概念,但我不明白如何正确使用它。

我的API正在向我发送此数据:

{
    gameweek: [
        {
          commonID: '23',
          content: 'blablabla',
          game: [
              {
                   commonID: '23',
                   gameID: 4,
                   title: 'first game'
              },
              {
                   commonID: '23',
                   gameID: 8,
                   title: 'second game'
              }
          ]
        },
        {
          commonID: '24',
          content: 'blebleble'
          game: [
              {
                   commonID: '24',
                   gameID: 12,
                   title: 'another game'
              }
          ]
        }
    ]
}

如您所见,我收到一个包含一些数据和另一个数组的数组。

如果我只有一个型号,我真的不知道如何创建模型?或像这样多个? (纠正我,如果错了):

//gameweek.js
import DS from "ember-data";

export default DS.Model.extend({
    commonID:       DS.attr('string'),
    title:          DS.attr('string'),
    games:          DS.hasMany('game')
});

//game.js
import DS from "ember-data";

export default DS.Model.extend({
    commonID:         DS.attr('string'),
    title:            DS.attr('string'),
    gameweek:         DS.belongsTo('gameweek')
});

我希望能够将我的数组保存在商店中并保持它们之间的关系。

如果我做this.store.find('gameweek', {commonID: '23'} );我想获得与游戏周相关的所有游戏。 (如果相关,则commonID​​将是相同的。)

我是否必须创建自定义序列化程序?

这么多问题,谢谢你的帮助!

=============================

更新:

我试图像这样扩展DS.RESTSerializer

export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
    extractArray: function( store, type, record ) {
        var gameweek = record.predictions;
        gameweek.forEach(function( entry ) {
            var data = entry.games.map(function(game) {
                return game.gameID;
            });
            entry.games = data;
        });
        record = { prediction: gameweek };
        return this._super( store, type, record );
    }
});

这主要是用gameID数组替换我的游戏数组,新数组如下所示:

{
        gameweek: [
            {
              commonID: '23',
              content: 'blablabla',
              game: ["4", "8"]
            },
            {
              commonID: '24',
              content: 'blebleble'
              game: ["12"]
            }
        ]
    }

但是我收到了这个错误: Error: Assertion Failed: Unable to find transform for 'integer'

我不知道该怎么做。

===================================

UPDATE2:

我也试过了:

//serializers/gameweek.js

import DS from "ember-data";

export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
    primaryKey: 'gameWeekID',
    attrs: {
       game: { embedded: 'load' }
    },
    extractArray: function( store, type, record ) {
        // The array of object isn't at the root structure of the record
        var record = record.predictions;
        record = { prediction: record };
        return this._super( store, type, record );
    }
});

//serializers/game.js
import DS from "ember-data";

export default DS.RESTSerializer.extend({
    primaryKey: 'gameID'
});

我收到了这个错误: Error: Assertion Failed: Ember Data expected a number or string to represent the record(s) in the "games" relationship instead it found an object. If this is a polymorphic relationship please specify a "type" key. If this is an embedded relationship please include the "DS.EmbeddedRecordsMixin" and specify the "games" property in your serializer's attrs object.

2 个答案:

答案 0 :(得分:0)

在ember中,你不要将数组保存为模型,将对象保存为模型。 Ember数据需要以某种方式返回数据,因此您需要执行此服务器端或使用序列化程序执行此操作 如果你的模型设置清楚,你可以保存关系没问题 在以下来自余烬网站的代码中,您的模型是一个帖子。因此,当您查询帖子时,这应该返回。帖子与评论有关系。帖子有很多评论和评论属于帖子。在post模型中,每个注释的id都与该帖子相关,然后注释作为单独的数组包含在内。 http://guides.emberjs.com/v1.12.0/models/the-rest-adapter/#toc_sideloaded-relationships

{
  "post": {
    "id": 1,
    "title": "Node is not omakase",
    "comments": [1, 2, 3]
  },

  "comments": [{
    "id": 1,
    "body": "But is it _lightweight_ omakase?"
  },
  {
    "id": 2,
    "body": "I for one welcome our new omakase overlords"
  },
  {
    "id": 3,
    "body": "Put me on the fast track to a delicious dinner"
  }]
}

上述结构的相关模型文件是
应用/模型/ post.js

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

应用/模型/ comment.js

export default DS.Model.extend({
  body: DS.attr('string'),
  post: DS.belongsTo('post')
});

我不知道它只是我的脑袋或它的结束,但上面的命名和结构布局非常令人困惑。您是否可以包含更多细节或使细节不那么通用,它可能有助于尝试计算数据。

答案 1 :(得分:0)

您应该为gameweekgame设置单独的模型。 Ember Data使用更精细的模型更好地工作,而不是尝试处理作为原始对象的模型字段。这将使得将来使用其他功能(例如计算属性和验证器)扩展游戏模型变得容易。所以你建议的模型结构很好。

但是,要使用当前的JSON结构,您必须声明game 嵌入。要做到这一点

// serializers/gameweek.js
import ApplicationSerializer from './application';
import DS from 'ember-data';
export default ApplicationSerializer.extend(DS.EmbeddedRecordsMixin, {
    attrs: {
        games: { embedded: 'load' }
    }
});

我们从ApplicationSerializer作为最佳实践继承,如果它指定了这些特定于模型的序列化程序继承的东西。

此外,Ember Data将坚持每个游戏的唯一ID,因此它有一种方法可以在商店中识别它。如果gameId是唯一的,您可以按原样使用,但您必须通过说

让Ember Data知道
// serializers/game.js
import ApplicationSerializer from './application';
import DS from 'ember-data';
export default ApplicationSerializer.extend({
    primaryKey: 'gameId'
});

执行此操作后,您将不再将ID称为gameId;您将其称为id,并且您不需要也不应该将其声明为模型的一部分。