将ActionScript对象映射到类?
如果我有一堆普通的旧对象,将它们映射到一堆类的最佳方法是什么?将ActionScript对象映射到类?
例如,如果我使用的HTTPService在一些JSON拉,然后反序列化,我有一堆看起来像对象:
{ type: "person",
id: 42,
name: "David" }
而且我想他们变成的实例一个人类:
class Person {
id:int;
name:String;
}
是否有一些标准的,一般的做法呢?
(也被认为是:怎么样处理对象之间的关系的一些标准的方式。例如,如果人有一个额外的“配偶”字段:?
{ type: "person", spouse: 61, ... } // Where 61 is the ID of the spouse
)
谢谢, 大卫
有没有这样做的标准方式,但你可以用两种不同的方式解决它。
版本1:构造方法
public class Person {
public function Person(raw:Object=null) {
if (raw != null) {
for (var key:String in raw) {
try {
this[key] = raw[key];
} catch (e:Error) {}
}
...
这是一种容易出错的。如果名称为的键不存在,则分配将失败,如果类型不匹配或不能自动被强制转换,它也会失败。
版本2:flash.utils.describeType()
复杂得多,给你更多的控制。首先,您必须创建一个Person实例并调用describeType()。
var o:Object = { ... } // raw person data
var p:Person = new Person();
var typeDesc:XML = flash.utils.describeType(p);
for (var key:String in o) {
var node:XML = typeDesc.variable.(@name==key)[0];
if (node != null) {
// Person class has a property *key*
p[key] = o[key];
}
}
但要小心使用getters和setter而不是公共变量。你不能用typeDesc.variable来访问它们,而是你必须使用typeDesc.accessor并检查它的访问属性是不是writeonly。
关于您的类型键。加载类动态,你可以这样做:
当然var clazz:Class = flash.utils.getDefinitionByName(raw.type+"");
var person:Person = Person(new clazz());
中raw.type可能包含人或com.package.Person只要你的目标类存在并且正在与该项目或动态编译加载SWC。
看看:
http://livedocs.adobe.com/flex/3/langref/flash/utils/package.html#getDefinitionByName() 和http://livedocs.adobe.com/flex/3/langref/flash/utils/package.html#describeType()
希望这有助于:)
是的,它的确如此 - 非常感谢。 – 2009-06-17 17:54:24
要保持干净的东西且不易出错,我会使用不同的对象来完成两项任务。例如,为了处理转换,你可能有以下对象:
public class PersonFactory
{
function buildFromGenerics(objects:Array):Array
{
var a:Array = [];
var l:int = objects.length;
for (var i:int = 0; i < l; i++)
{
var o:Object = objects[i];
var p:Person = new Person();
p.id = o['id'];
p.name = o['name'];
a[i] = p
}
return a;
}
}
迁移所有的这一步的逻辑放到一个单独的对象可以隔离这个功能,这确实是独立于实际Person对象的,所以没有快乐在那里。
对于第二种情况下我会使用一个单独的对象,拥有它你Person对象,并提供一个接口,用于检索它们,这表现在这里:
public class PersonCollection
{
private var _people:Array;
public function setPeople(people:Array):void
{
_people = people;
}
public function getPersonByID(id:int):Person
{
var l:int = _people.length;
for (var i:int = 0; i < l; i++)
{
var p:Person = _people[i];
if (p.id == id)
{
return p;
}
}
return null;
}
}
这种分离有助于保持你的代码干净,并提供了一个简单的方法来处理和管理它。希望有所帮助。
你使用AMF来接收你的数据吗? – Josh 2009-06-16 19:30:34
否...如果我使用AMF,这会更容易,但其他事情(特别是服务器端代码)会变得更加复杂。 – 2009-06-17 17:52:17