我需要使用localStorage存储一些Ember对象。我注意到Ember对象具有名称为__ember1334992182483
的属性。当我在Ember对象上调用JSON.stringify()
时,这些__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对象的最佳方法吗?是否有推荐的技术?
答案 0 :(得分: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
答案 1 :(得分:0)
我会使用ember-data并为此编写数据存储适配器。
答案 2 :(得分: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:""
})
*/