如何使用Ember Data的FixtureAdapter和真实的API内容

时间:2014-09-08 21:45:21

标签: ember-data fixtures

我想用我的Ember Data灯具填充从API数据转储而不是标准灯具中获取的真实内容。我不想直接使用API​​。

我想这样做,所以我可以模仿API数据的本地实例。

如何简化此操作以及如何配置适配器以允许此操作?

考虑这个默认的FIXTURE:

App.Comment = DS.Model.extend({
    article: DS.belongsTo('article'),
    author: DS.belongsTo('user'),
    dateCreated: DS.attr('date', {readOnly: true}),
    dateModified: DS.attr('date', {readOnly: true}),
    description: DS.attr('string')
});

App.Comment.FIXTURES = [{
    id: 1,
    temp: 1,
    author: 1,
    dateCreated: 'Mon Jul 28 2014 12:00:00 GMT+1000 (EST)',
    dateModified: null,
    description: 'lorem ipsum'
}];

考虑这个API响应:

{"comments": [
  {
    "articleID": 1,
    "description": "I am a comment",
    "authorID": 1,
    "dateCreated": "2014-09-04T02:39:00",
    "createdBy": "Elise Chant",
    "dateModified": "2014-09-04T02:39:00",
    "id": 1
  },
  {
    "articleID": 1,
    "description": "I am another comment",
    "authorID": 1,
    "dateCreated": "2014-09-04T02:48:00",
    "createdBy": "Elise Chant",
    "dateModified": "2014-09-04T02:48:00",
    "id": 2
  }
]}

1 个答案:

答案 0 :(得分:0)

让您的后端从API提供数据转储方法和资源,例如:

http://myapi/dump

该方法应返回表示网站资源的压缩文件夹,例如Comment.jsUser.jsArticle.js

这些文件中的每一个都应该返回由DS.Model.FIXTURES数组包装的JSON资源,例如

App.Comment.FIXTURES = 
[
  {
    "articleID": 1,
    "userID": 1,
    "description": "I am a comment.",
    "category": 0,
    "authorID": 1,
    "dateCreated": "2014-09-04T02:39:00",
    "id": 1
  },
  // ...
];

请记住确保每个.js文件都是html中包含的脚本标记,并显示在相应的模型之后。检查这在浏览器的开发者控制台中可用。

最后,为了正确连接articleIDauthorID等异步关系,需要对属性名称进行规范化,就像使用普通的fixture数据一样。因此,通过解析FIXTURES有效负载,将适配器配置为从任何belongsTo关系的末尾去除“ID”:

if (App.ENV === 'DEV') {

    App.ApplicationSerializer = DS.JSONSerializer.extend({

        // access to the payload
        extractArray: function(store, type, payload) {
            var self = this;
            return payload.map(function(item) {
                // normalise incoming data
                return self.normalize(type, item);
            });
        },

        normalize: function(type, hash) {
            if (!hash) { return hash; }

            var normalizedHash = {},
                normalizedProp;

            for (var prop in hash) {
                if (!!prop.match(/ID$/)) {
                    // belongs to / has Many attribute
                    // remove 'ID' from the end of the property name
                    normalizedProp = prop.substr(0, prop.length-2);
                } else {   // regular attribute
                    normalizedProp = prop;
                }

                normalizedHash[normalizedProp] = hash[prop];
            }

            this.normalizeId(normalizedHash);
            this.normalizeUsingDeclaredMapping(type, normalizedHash);
            this.applyTransforms(type, normalizedHash);
            return normalizedHash;
        }
    });

    App.ApplicationAdapter = DS.FixtureAdapter.extend({
        simulateRemoteResponse: true,
        latency: 1000,
        // This "unsets" serializer so that the store will lookup the proper serializer
        // @see https://github.com/emberjs/data/issues/1333
        serializer: function() {
            return;
        }.property()
    });

} else {

    DS.CustomRESTSerializer = DS.RESTSerializer.extend({
        keyForRelationship: function(key, kind) {
            if (kind === 'belongsTo') {
                return key + 'ID';
            } else {
                return key;
            }
        }
    });

    App.ApplicationAdapter = DS.RESTAdapter.extend({
        host: App.HOST,
        namespace: App.NAMESPACE,
        ajax: function(url, method, hash) {
            hash = hash || {}; // hash may be undefined
            hash.crossDomain = true;
            hash.xhrFields = {withCredentials: true};
            return this._super(url, method, hash);
        },
        defaultSerializer: 'DS/customREST'
    });

}