Ember модель в json

Я ищу эффективный способ преобразовать мой объект Ember в строку json, чтобы использовать ее в сообщении websocket ниже

/*
 * Model
 */

App.node = Ember.Object.extend({
  name: 'theName',
  type: 'theType',
  value: 'theValue',
})

Метод websocket:

App.io.emit('node', {node: hash}); 

hash должен быть json-представлением узла. {name: thename, type: theType, ..} Должен быть быстрый onliner, чтобы сделать это... Я не хочу делать это вручную, так как у меня много атрибутов и они могут меняться...

22
задан geoffreyd 2 January 2012 в 02:33
поделиться

4 ответа

У меня есть:

  • исправлен и упрощен код
  • добавлено предотвращение циклических ссылок
  • добавлено использование получения значения
  • удалены все свойства по умолчанию для пустого компонента

    //Modified by Shimon Doodkin 
    //Based on answers of: @leo, @pangratz, @kevin-pauli, @Klaus
    //http://stackoverflow.com/questions/8669340
    
    App.Jsonable = Em.Mixin.create({
        getJson : function (keysToSkip, visited) {
            //getJson() called with no arguments,
            // they are to pass on values during recursion.
    
            if (!keysToSkip)
                keysToSkip = Object.keys(Ember.Component.create());
    
            if (!visited)
                visited = [];
    
            visited.push(this);
    
            var getIsFunction;
    
            var jsonValue = function (attr, key, obj) {
                if (Em.isArray(attr))
                    return attr.map(jsonValue);
                if (App.Jsonable.detect(attr))
                    return attr.getJson(keysToSkip, visited);
                return getIsFunction?obj.get(key):attr;
            };
    
            var base;
            if (!Em.isNone(this.get('jsonProperties')))
                base = this.getProperties(this.get('jsonProperties'));
            else
                base = this;
    
            getIsFunction=Em.typeOf(base.get) === 'function';
    
            var json = {};
    
            var hasProp = Object.prototype.hasOwnProperty;
    
            for (var key in base) {
    
                if (!hasProp.call(base, key) || keysToSkip.indexOf(key) != -1)
                    continue;
    
                var value = base[key];
    
                // there are usual circular references
                // on keys: ownerView, controller, context === base
    
                if ( value === base ||
                     value === 'toString' ||
                     Em.typeOf(value) === 'function')
                    continue;
    
                // optional, works also without this,
                // the rule above if value === base covers the usual case
                if (visited.indexOf(value) != -1)
                    continue;
    
                json[key] = jsonValue(value, key, base);
    
            }
    
            visited.pop();
            return json;
        }
    });
    
    /*
    example:
    
    DeliveryInfoInput = Ember.Object.extend(App.Jsonable,{
     jsonProperties: ["title","value","name"], //Optionally specify properties for json
     title:"",
     value:"",
     input:false,
     textarea:false,
     size:22,
     rows:"",
     name:"",
     hint:""
    })
    */
    
0
ответ дан 29 November 2019 в 04:49
поделиться

Я написал обширную статью о том, как вы можете конвертировать модели ember в собственные объекты или JSON, которые могут помочь вам или другим:)

http://pixelchild.com. au / post / 44614363941 / как конвертировать угольные объекты в json

http://byronsalau.com/blog/convert-ember-objects -в-JSON /

3
ответ дан 29 November 2019 в 04:49
поделиться

Я также боролся с этим. Как говорит Мирко, если вы передадите объект ember в JSON.stringify, вы получите ошибку циклической ссылки. Однако, если вы храните объект в одном свойстве и используете для него stringify, он работает, даже если вложенные свойства принадлежат.

var node = Ember.Object.create({
  data: {
    name: 'theName',
    type: 'theType',
    value: 'theValue'
  }
});

console.log(JSON.stringify(node.get('data')));

Однако, это работает только в Chrome, Safari и Firefox. В IE8 я получаю переполнение стека, так что это не жизнеспособное решение.

Я прибег к созданию JSON-схем для своих объектных моделей и написал рекурсивную функцию для итерации по объектам с использованием свойств в схемах, а затем для создания чистых объектов Javascript, которые затем я могу преобразовать в строку и отправить на свой сервер. Я также использую схемы для проверки, так что это решение работает довольно хорошо для меня, но если у вас очень большие и динамические модели данных, это невозможно. Мне также интересны более простые способы сделать это.

4
ответ дан 29 November 2019 в 04:49
поделиться

Я изменил решение @ Kevin-pauli, чтобы оно работало также и с массивами:

App.Jsonable = Ember.Mixin.create({
    getJson: function() {
        var v, json = {}, inspectArray = function (aSome) {
            if (Ember.typeof(aSome) === 'array') {
                return aSome.map(inspectArray);
            }
            if (Jsonable.detect(aSome)) {
                return aSome.getJson();
            } 
            return aSome;
        };
        for (var key in this) {
            if (this.hasOwnProperty(key)) {
                v = this[key];
                if (v === 'toString') {
                    continue;
                } 
                if (Ember.typeOf(v) === 'function') {
                    continue;
                }
                if (Ember.typeOf(v) === 'array') {
                    v = v.map(inspectArray);
                }
                if (App.Jsonable.detect(v))
                    v = v.getJson();
                json[key] = v;
            }
        }
        return json;
    }
});

Я также внес некоторые дополнительные изменения, чтобы получить лучшее из обоих миров. В следующей версии я проверяю, обладает ли объект Jsonable определенным свойством, которое информирует меня о том, какие из его свойств следует сериализовать:

App.Jsonable = Ember.Mixin.create({
    getJson: function() {
        var v, json = {}, base, inspectArray = function (aSome) {
            if (Ember.typeof(aSome) === 'array') {
                return aSome.map(inspectArray);
            }
            if (Jsonable.detect(aSome)) {
                return aSome.getJson();
            } 
            return aSome;
        };
        if (!Ember.isNone(this.get('jsonProperties'))) {
            // the object has a selective list of properties to inspect
            base = this.getProperties(this.get('jsonProperties'));
        } else {
            // no list given: let's use all the properties
            base = this;
        }
        for (var key in base) {
            if (base.hasOwnProperty(key)) {
                v = base[key];
                if (v === 'toString') {
                    continue;
                } 
                if (Ember.typeOf(v) === 'function') {
                    continue;
                }
                if (Ember.typeOf(v) === 'array') {
                    v = v.map(inspectArray);
                }
                if (App.Jsonable.detect(v))
                    v = v.getJson();
                json[key] = v;
            }
        }
        return json;
    }
});

Я использую этот небольшой твик и доволен им. Я надеюсь, что это поможет и другим!

Спасибо @pangratz и @ Kevin-Pauli за их решение!

1
ответ дан 29 November 2019 в 04:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: