RESTSerializer扩展不影响Ember数据对象

时间:2015-08-04 19:41:08

标签: ember.js sails.js

来自Sails响应的JSON没有root元素。 Ember数据要求将JSON包装在与根对象名称相同的根元素中。计划是扩展RESTSerializer以在客户端使用JSON,因为我没有对我从中获取此数据的服务器进行类似的控制。我不确定我做错了什么,但我的帐户模型似乎并没有使用我的AccountSerializer ...

这是我的Serializer:

var AccountSerializer = DS.RESTSerializer.extend({
/**
 The current ID index of generated IDs
 @property
 @private
 */
_generatedIds: 0,
/**
 Sideload a JSON object to the payload

 @method sideloadItem
 @param {Object} payload   JSON object representing the payload
 @param {subclass of DS.Model} type   The DS.Model class of the item to be sideloaded
 @param {Object} item JSON object   representing the record to sideload to the payload
 */
sideloadItem: function(payload, type, item){
    var sideloadKey = type.typeKey.pluralize(), // The key for the sideload array
        sideloadArr = payload[sideloadKey] || [],   // The sideload array for this item
        primaryKey = Ember.get(this, 'primaryKey'), // the key to this record's ID
        id = item[primaryKey];

    // Missing an ID, generate one
    if (typeof id == 'undefined') {
        id = 'generated-'+ (++this._generatedIds);
        item[primaryKey] = id;
    }

    // Don't add if already side loaded
    if (sideloadArr.findBy("id", id) != undefined){
        return payload;
    }

    // Add to sideloaded array
    sideloadArr.push(item);

    payload[sideloadKey] = sideloadArr;
    return payload;
},

/**
 Extract relationships from the payload and sideload them. This function recursively
 walks down the JSON tree

 @method sideloadItem
 @param {Object} payload   JSON object representing the payload
 @paraam {Object} recordJSON   JSON object representing the current record in the payload to look for relationships
 @param {Object} recordType   The DS.Model class of the record object
 */
extractRelationships: function(payload, recordJSON, recordType){

    // Loop through each relationship in this record type
    recordType.eachRelationship(function(key, relationship) {
        var related = recordJSON[key], // The record at this relationship
            type = relationship.type;  // belongsTo or hasMany

        if (typeof related === "object" && related !== null){

            // One-to-one
            if (relationship.kind == "belongsTo") {
                // TODO: figure out when we need to only sideload 1 item we don't need to pluralize
                // Sideload the object to the payload
                this.sideloadItem(payload, type, related);

                // Replace object with ID
                recordJSON[key] = related.id;

                // Find relationships in this record
                this.extractRelationships(payload, related, type);
            }

            // Many
            else if (relationship.kind == "hasMany") {

                // Loop through each object
                related.forEach(function(item, index){

                    // Sideload the object to the payload
                    this.sideloadItem(payload, type, item);

                    // Replace object with ID
                    related[index] = item.id;

                    // Find relationships in this record
                    this.extractRelationships(payload, item, type);
                }, this);
            }

        }
    }, this);

    return payload;
},


/**
 Overrided method
 */
extractArray: function(store, type, payload, id, requestType) {
    var typeKey = type.typeKey,
        typeKeyPlural = typeKey.pluralize(),
        newPayload = {};

    newPayload[typeKeyPlural] = payload;

    payload = newPayload;

    console.log(payload);


    // Many items (findMany, findAll)
    if (typeof payload[typeKeyPlural] != "undefined"){
        payload[typeKeyPlural].forEach(function(item, index){
            this.extractRelationships(payload, item, type);
        }, this);
    }

    for(var key in payload) {
        if(key === typeKeyPlural) {
            for(var i =0; i < payload[key].length; i++) {
                if(typeof payload[key][i] !== 'object') {
                    delete payload[key][i];
                }
            }
        }
    }

    return this._super(store, type, payload, id, requestType);
},

extractSingle: function (store, type, payload, id, requestType) {
    console.log('what is happening');
    var typeKey = type.typeKey,
        typeKeyPlural = typeKey.pluralize(),
        newPayload = {};

    if(typeof payload[typeKey] !== "object") {
        newPayload[typeKey] = payload;
        payload = newPayload;

        if(payload[typeKey] instanceof Array) {
            payload[typeKey] = payload[typeKey][0];
        }
    }


    if (typeof payload[typeKey] === "object"){
        this.extractRelationships(payload, payload[typeKey], type);

        delete payload[typeKeyPlural];
    }

    console.log(payload);


    return this._super(store, type, payload, id, requestType);
}
});
export default AccountSerializer;

在我的adapter / account.js中,我有以下内容:

import DS from "ember-data";

var AccountAdapter = DS.RESTAdapter.extend({
  namespace: 'api/v1',
  host: 'http://localhost:5000',
  pathForType: function(type) {
    return type + '.json';
  },
  serializer: AccountSerializer
});

export default AccountAdapter;

1 个答案:

答案 0 :(得分:2)

我并非100%确定您从哪里获得serializer财产,但我不确定其实际存在。适配器上有一个defaultSerializer属性可以工作,但是它带有一些奇怪的优先级规则。如果我是你,我会通过将序列化程序放入serializers/account.js并将其从适配器中删除serializer属性来以Ember CLI方式声明序列化程序。