2012-04-21 11 views
6

Necesito usar localStorage para almacenar algunos objetos Ember. Noté que los objetos Ember tienen propiedades con nombres como __ember1334992182483. Cuando llamo al JSON.stringify() en objetos Ember, estas propiedades __ember* no se serializan. ¿Por qué es esto? No digo que quiera serializar esas propiedades. Solo tengo curiosidad sobre qué son exactamente y cómo se implementan de manera que no se serialicen.¿Cómo se serializan los objetos Ember?

Estoy utilizando cycle.js (https://github.com/douglascrockford/JSON-js/blob/master/cycle.js) para codificar mis estructuras de datos que contienen referencias duplicadas en una cadena que se puede utilizar para reconstruir las estructuras de datos originales. Se le permite hacer esto:

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 

Para objetos Ember puedo hacer lo mismo, pero también necesita pasar los objetos deserialised en Ember.Object.create() porque están deserialised como objetos JavaScript lisos.

¿Es esta la mejor manera de serializar/deserializar objetos Ember? ¿Hay una técnica recomendada para esto?

Respuesta

0

Utilizaría ember-data y escribiría un adaptador de almacén de datos para esto.

8

para la serialización y deserialización se podría hacer algo a lo largo de estas líneas, ver 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());​ 

ACTUALIZACIÓN: También echar un vistazo a la pregunta similar Ember model to json

+0

¿Por qué el '__ember *' propiedades que no están en la salida de 'JSON.stringify()'? – hekevintran

+0

Tengo que adivinar aquí ya que no soy un experto en JavaScript: pero si haces un 'for (prop in obj) {}' en un 'Ember.Object', no se incluye' __ember * 'y se verifica' obj.hasOwnProperty' solo devuelve verdadero para las propiedades definidas, ver http://jsfiddle.net/pangratz666/w53DH/. – pangratz

+0

Las propiedades '__ember *' no aparecen en el bucle 'for ... in'. Al hacer 'App.obj.hasOwnProperty ('__ ember1335029966963')' se devuelve 'true'. – hekevintran

0

tengo:

  • fixe dy código simplificado
  • prevención añadido referencia circular
  • uso añadido de get del valor
  • eliminado todas las propiedades por defecto de un componente de vacío

    //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:"" 
    }) 
    */ 
    
Cuestiones relacionadas