2012-04-21 10 views
6

Devo usare localStorage per memorizzare alcuni oggetti di tipo Ember. Ho notato che gli oggetti Ember hanno proprietà con nomi come __ember1334992182483. Quando chiamo JSON.stringify() su oggetti Ember, queste proprietà __ember* non sono serializzate. Perchè è questo? Non sto dicendo che voglio serializzare quelle proprietà. Sono solo curioso di sapere esattamente cosa sono e come sono implementati in modo tale da non essere serializzati.Come si serializzano oggetti Ember?

Sto usando cycle.js (https://github.com/douglascrockford/JSON-js/blob/master/cycle.js) per codificare le mie strutture di dati che contengono riferimenti duplicati in una stringa che può essere utilizzata per la ricostruzione delle strutture di dati originali. Ti permette di fare questo:

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 

Per gli oggetti tempora che posso fare la stessa cosa, ma ho anche bisogno di passare gli oggetti deserialised in Ember.Object.create() perché sono deserialised come oggetti JavaScript pianura.

È questo il modo migliore per serializzare/deserializzare gli oggetti di legno? C'è una tecnica consigliata per questo?

risposta

0

Vorrei utilizzare ember-data e scrivere un adattatore datastore per questo.

8

per la serializzazione e deserializzazione si potrebbe fare qualcosa lungo questa linea, vedi 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());​ 

UPDATE: hanno anche uno sguardo alla domanda simile Ember model to json

+0

Perché sono il '__ember *' proprietà non nell'output di 'JSON.stringify()'? – hekevintran

+0

Devo indovinare da quando non sono un esperto di JavaScript: ma se fai un 'for (prop in obj) {}' su un 'Ember.Object', non viene elencato' __ember * 'e un controllo per' obj.hasOwnProperty' restituisce solo true per le proprietà definite, vedere http://jsfiddle.net/pangratz666/w53DH/. – pangratz

+0

Le proprietà '__ember *' non vengono elencate nel ciclo 'for ... in'. Facendo 'App.obj.hasOwnProperty ('__ ember1335029966963')' restituisce 'true'. – hekevintran

0

ho:

  • fix d e codice semplificato
  • prevenzione aggiunto riferimento circolare
  • uso aggiunto di get value
  • rimosso tutte le proprietà predefinite di un componente vuoto

    //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:"" 
    }) 
    */ 
    
Problemi correlati