6

いくつかの Ember オブジェクトを格納するために localStorage を使用する必要があります。Ember オブジェクトには のような名前のプロパティがあることに気付きました__ember1334992182483JSON.stringify()Ember オブジェクトを呼び出すと、これらの__ember*プロパティはシリアル化されません。どうしてこれなの?これらのプロパティをシリアライズしたいと言っているのではありません。それらが正確に何であり、それらがシリアル化されないようにどのように実装されているかについて、私はただ興味があります。

cycle.js ( https://github.com/douglascrockford/JSON-js/blob/master/cycle.js ) を使用して、重複参照を含むデータ構造を元のデータの再構築に使用できる文字列にエンコードしています構造。これを行うことができます:

a = {a:1}
b = {b:1}
c = [[a, b], [b, a]]

foo = JSON.stringify(JSON.decycle(c))  // "[[{'a':1},{'b':1}],[{'$ref':'$[0][1]'},{'$ref':'$[0][0]'}]]"
JSON.retrocycle(JSON.parse(foo))  // reconstruct c

Ember オブジェクトの場合も同じことができますが、逆シリアル化されたオブジェクトを に渡す必要もあります。これらのEmber.Object.create()オブジェクトはプレーンな JavaScript オブジェクトとして逆シリアル化されるためです。

これは Ember オブジェクトをシリアライズ/デシリアライズする最良の方法ですか? これに推奨されるテクニックはありますか?

4

3 に答える 3

8

シリアライゼーションとデシリアライゼーションについては、この行に沿って何かを行うことができます。 http://jsfiddle.net/pangratz666/NVpng/を参照してください。

App.Serializable = Ember.Mixin.create({
    serialize: function() {
        var propertyNames = this.get('propertyNames') || [];
        return this.getProperties(propertyNames);
    },

    deserialize: function(hash) {
        this.setProperties(hash);
    }
});

App.Person = Ember.Object.extend(App.Serializable, {
    propertyNames: 'firstName title fullName'.w(),
    fullName: function() {
        return '%@ %@'.fmt(this.get('title'), this.get('firstName'));
    }.property('firstName', 'title')
});

var hansi = App.Person.create({
    firstName: 'Hansi',
    title: 'Mr.'
});

// { firstName: 'hansi', title: 'Mr.', fullName: 'Mr. Hansi' }
console.log( hansi.serialize() );

var hubert = App.Person.create();
hubert.deserialize({
    firstName: 'Hubert',
    title: 'Mr.'
});
console.log( hubert.serialize() );​

更新:同様の質問Ember model to json もご覧ください

于 2012-04-21T15:31:11.093 に答える
0

私は持っている:

  • 固定および簡素化されたコード
  • 循環参照防止を追加
  • 値の取得の追加使用
  • 空のコンポーネントのデフォルト プロパティをすべて削除

    //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:""
    })
    */
    
于 2015-11-04T22:21:43.337 に答える
0

私は ember-data を使用して、これ用のデータストア アダプターを作成します。

于 2012-04-21T14:18:33.617 に答える