2012-04-21 19 views
6

Potrzebuję użyć localStorage do przechowywania niektórych obiektów Ember. Zauważam, że obiekty Ember mają właściwości o nazwach takich jak __ember1334992182483. Kiedy wywołuję JSON.stringify() na obiektach Ember, te właściwości __ember* nie są serializowane. Dlaczego to? Nie mówię, że chcę serializować te właściwości. Jestem tylko ciekawy, czym dokładnie są i jak są one realizowane tak, że nie są serializowane.Jak serializować obiekty Ember?

Używam cycle.js (https://github.com/douglascrockford/JSON-js/blob/master/cycle.js) do kodowania struktur danych, które zawierają zduplikowane odwołania do ciągu, który może być użyty do rekonstrukcji oryginalnych struktur danych. Pozwala to zrobić:

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 

Dla obiektów Ember mogę zrobić to samo, ale muszą także zdać deserialised przedmiotów do Ember.Object.create() ponieważ są deserialised jako zwykły obiektów JavaScript.

Czy to najlepszy sposób na serializację/deserializację obiektów Ember? Czy istnieje zalecana technika?

Odpowiedz

0

Chciałbym używać danych ember i napisać adapter do datastore do tego.

8

Dla serializacji i deserializacji mógłby zrobić coś wzdłuż tej linii, zobacz 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: Mają również spojrzeć na podobne pytanie Ember model to json

+0

Dlaczego są '__ember *' właściwości nie na wyjściu 'JSON.stringify()'? – hekevintran

+0

Muszę zgadywać tutaj, ponieważ nie jestem ekspertem od JavaScript: ale jeśli zrobisz 'for (prop w obj) {}' na 'Ember.Object', to nie ma' __ember * 'i sprawdź dla'. obj.hasOwnProperty' zwraca tylko wartość true dla zdefiniowanych właściwości, zobacz http://jsfiddle.net/pangratz666/w53DH/. – pangratz

+0

Właściwości '__ember *' nie są wymienione w pętli 'for ... in'. Wykonanie 'App.obj.hasOwnProperty ('__ ember1335029966963')' zwraca 'true'. – hekevintran

0

mam:

  • fixe d i uproszczony kod
  • zapobieganie dodaje odwołanie cykliczne
  • dodany wykorzystanie GET wartości
  • usunięto wszystkie właściwości domyślnych pustego elementu

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