问题
I have an object model that I want to be able to save. I am going to export it to JSON and then read it back in as JSON.
Saving to JSON is easy. Just use this: JSON.stringify(this)
.
Loading from JSON isn't as simple.
- We can't just use
this = JSON.parse(someJson)
because the methods wont be attached. - Using something like
lang.mixin(this, JSON.parse(someJson))
will get the functions but objects that are
Photo Class:
define([...], function(...){
return declare(null, {
name: ..., // String
url:..., // String
complexProperty:..., // Some other class
someFunction1: function(...){..},
someFunction2: function(...){..},
someFunction2: function(...){..}
}
));
Photo Album Class:
define([...], function(...){
return declare(null, {
photos: [], /* Array of type Photo (see above) */
someOtherProperty: ...,
someOtherProperty: ...,
someFunction1: function(...){..},
someFunction2: function(...){..},
someFunction2: function(...){..},
toJson: function(){
return JSON.stringify(this); // From dojo/json
}
loadFromJson: function(jsonIn){
// How to do this?
},
/* This doesn't work because methods will be overridden */
loadFromJson1: function(jsonIn){
this = JSON.parse(someJson);
},
/* This insures that my methods are kept intact but my childrens methods arn't (ie: the array of photos) */
loadFromJson2: function(jsonIn){
lang.mixin(this, JSON.parse(someJson));
},
/* This seems like an aweful lot of work. Any better ways to do this? */
loadFromJson3: function(jsonIn){
this.someOtherProperty = jsonIn.someOtherProperty;
this.someOtherProperty = jsonIn.someOtherProperty;
foreach(jsonIn.photos: photoJson){
var newPhoto = new Photo();
newPhoto.loadfromJson(photoJson);
this.photos.add(newPhoto);
}
... All other properties set recursively. All things in model now need this method ...
}
}
));
回答1:
I think you would be better off returning a JSON object that contains just the data you need to serialize, not the whole class. Then your loadFromJson method would be a little easier to implement, and you wont be sending unnecessary data over the network. Example toJson():
toJson: function() {
return JSON.stringify({
photos: this.photos,
someImportantProp: this.someImportantProp,
anotherProp: this.anotherProp
});
}
回答2:
JSON is not the same thing as a JavaScript object, in fact, it's only a subset. JSON only allows arrays, objects and of course basic types like Strings, booleans, numbers and null
. You can find the entire specification here.
If you really want to keep the functions you can use the eval()
function, but this is not really recommended, because it indeed parses those functions. If the evaluated content contains malicious input, then that is being executed as well.
For example:
eval("myObj = { getSum: function getSum(a, b) { return a + b; } }");
myObj.getSum(1, 2); // Returns 3
You can better attempt to save the state of the object (name
and url
for example) and rebuild it once you parse it again, that is what happens in other programming languages as well. For example, if you're serializing/deserializing an object in Java.
来源:https://stackoverflow.com/questions/22945894/dojo-how-to-load-an-object-containing-other-objects-from-json