Javascript Sails.JSON到余烬

Javascript Sails.JSON到余烬,javascript,json,ember.js,sails.js,Javascript,Json,Ember.js,Sails.js,我正在试验Sails.JS和Ember.JS 不幸的是,在这种情况下,Ember希望json的格式是正确的。Sails.JSON如下所示: // specific game // /api/game/1 { cards: [ { id: 2, createdAt: "2014-04-10T13:15:47.259Z", updatedAt: "2014-04-10T13:15:47.259Z",

我正在试验Sails.JS和Ember.JS

不幸的是,在这种情况下,Ember希望json的格式是正确的。Sails.JSON如下所示:

// specific game
// /api/game/1
{
    cards: [
        {
            id: 2,
            createdAt: "2014-04-10T13:15:47.259Z",
            updatedAt: "2014-04-10T13:15:47.259Z",
            game: 1,
            player: 1
        }
    ],
    table: {
        id: 1,
        createdAt: "2014-04-10T10:47:27.292Z",
        updatedAt: "2014-04-10T10:47:27.292Z"
    },
    serverSeed: "test",
    createdAt: "2014-04-10T13:15:03.872Z",
    updatedAt: "2014-04-10T13:15:03.872Z",
    id: 1
}

// all games
// api/game
[
    {
        cards: [
            {
                id: 2,
                createdAt: "2014-04-10T13:15:47.259Z",
                updatedAt: "2014-04-10T13:15:47.259Z",
                game: 1,
                player: 1
            }
        ],
        table: {
            id: 1,
            createdAt: "2014-04-10T10:47:27.292Z",
            updatedAt: "2014-04-10T10:47:27.292Z"
        },
        serverSeed: "test",
        createdAt: "2014-04-10T13:15:03.872Z",
        updatedAt: "2014-04-10T13:15:03.872Z",
        id: 1
    }
]
有什么好方法可以转换Sails.JSON或是一个Ember.js序列化程序来解决这个问题吗?

我稍微修改了代码,现在可以正常工作了

App.ApplicationSerializer = 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 (related){

                // One-to-one
                if (relationship.kind == "belongsTo") {
                    // 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;

        // 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];
                    }
                }

            }
        }

        console.log(payload);

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

    extractSingle: function (store, type, payload, id, requestType) {
        var typeKey = type.typeKey,
            typeKeyPlural = typeKey.pluralize(),
            newPayload = {};

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


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

                delete payload[typeKeyPlural];
            }
        }

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

哪种格式是哪种?无论哪种方式,唯一的区别是一个响应在一个数组中,另一个不是。将对象响应放入数组中,或在0索引处访问数组响应。这两个都是Sails.JS响应。第一个是对/api/game/1的调用,所以只有ID 1,第二个是对/api/game的调用,所以所有的游戏都会显示数组,如果我有更多的游戏,数组当然会更大。我只是想指出,从beta 7开始的余烬数据并不完全符合规范,这非常令人困惑。例如,jsonapi要求将所有响应包装在一个数组中,即使您只返回一项/games/1但如果返回的是倍数,即/games,则余烬数据只希望结果包装在数组中。我之前发布了一个示例,演示了ember data希望其json看起来像什么,您还可以看看自动为您实现了什么,并设置了整个后端和前端。