类型转换的最佳方法是反序列化JSON

时间:2010-03-05 10:19:45

标签: flex actionscript-3

我想我已经在as3corelib中建立了JSON.decode我别无选择,只能反序列化为一个普通的旧的flex对象。

var data:Object = JSON.decode(json);

如果我想将对象中包含的数据转换为另一种类型,我就不能使用类型转换。我必须实例化一个新实例并手动添加属性。

var data:Object = JSON.decode(json);
var model:Model = new Model();
model.name = data.name;
model.notes = data.notes;

痛苦而且有点难看,但我猜这是从无类型的json到flex类型的代价。我的第一个问题是我的假设是否正确,并且没有更漂亮的方法用json中包含的数据创建我的模型实例?

我的第二个问题,如果是这样,那么在我编写自己的方法之前,flex api中是否有任何内容可以获取数据对象并将其值混合到我的模型实例中?

干杯,

克里斯

2 个答案:

答案 0 :(得分:2)

我一直使用的方法被证明是ActionScript中AMF3序列化机制的一部分。

查看IExternalizableregisterClassAlias

现在我使用的是以下内容:

interface ISerializable {
    public function getRawData():Object;
    public function setRawData(param:Object):void;
}
function registerType(id:String, type:Class):void {
    //implementation
}
function getTypeByID(id:String):Class {
    //implementation
}
function getTypeID(type:Class):String {
    //implementation
}

并向解码器/编码器注册一个类别名。

对象的序列化工作原理如下:

var raw:Object = model.getRawData();
raw[" type"] = getTypeID(model);
var encoded:String = JSON.encode(raw);

解码的工作原理如下:

var raw:Object = JSON.decode(raw);
var cl:Class = getTypeByID(raw[" type"]);
if (cl == null) throw new Error("no class registered for type: "+raw[" type"]);
delete raw[" type"];
var model:ISerializable = new cl();
model.setRawData(raw);

你需要在整个反序列化的JSON树上递归地执行此操作,从叶子开始。 对于循环引用,您需要一个技巧。 我在某处实现了这个,但我找不到它。

答案 1 :(得分:1)

您可以在json解码对象的字段内循环并将它们分配到您的模型中:

function json2model(json:String):Model{
 var data:Object = JSON.decode(json);

 var m:Model=new Model();

 for (var field:String in data) {
  if (m.hasOwnProperty(field)) {
   m[field] = data[field];
  }
 }

 return m;
} 

var model:Model=json2model(json)

或者在你的模型中添加静态函数,如果你喜欢:

public class Model {
 //...
 public static function fromJSon(json:String):Model {
     var data:Object = JSON.decode(json);

     var m:Model=new Model();

     for (var field:String in data) {
      if (m.hasOwnProperty(field)) {
       m[field] = data[field];
      }
     }

     return m;
    } 
 }
}

var model:Model=Model.fromJSon(json);