Отображение объектов ActionScript в классы? - PullRequest
1 голос
/ 16 июня 2009

Если у меня есть куча простых старых объектов, как лучше всего сопоставить их с кучей классов?

Например, если я использую HTTPService для извлечения некоторого JSON, а затем десериализую его, у меня будет куча объектов, которые выглядят так:

{ type: "person",
  id: 42,
  name: "David" }

И я хочу превратить их в экземпляры класса Person:

class Person {
    id:int;
    name:String;
}

Есть ли какой-то стандартный, общий способ сделать это?

(также следует учитывать: как насчет стандартного способа работы с отношениями между объектами? Например, если у человека есть дополнительное поле "супруг":

{ type: "person", spouse: 61, ... } // Where 61 is the ID of the spouse

)

Спасибо, David

Ответы [ 2 ]

3 голосов
/ 17 июня 2009

Не существует стандартного способа сделать это, однако вы можете решить его двумя различными способами.

Версия 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) {}
   }
   ...

Это своего рода ошибка. Если свойство с именем key не существует, присваивание завершится ошибкой, а если тип не соответствует или не может быть принудительно приведен автоматически, то оно также завершится неудачей.

Версия 2: flash.utils.describeType ()

Гораздо сложнее, дает вам больше контроля. Сначала вы должны создать экземпляр Person и вызвать descriptionType ().

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];
 }
}

Но будьте осторожны при использовании геттеров и сеттеров вместо публичных переменных. Вы не можете получить к ним доступ с помощью typeDesc.variable, вместо этого вы должны использовать typeDesc.accessor и проверить, не является ли его атрибут доступа доступным только для записи.

Относительно вашего типа ключа. Для динамической загрузки класса вы можете сделать:

var clazz:Class = flash.utils.getDefinitionByName(raw.type+"");
var person:Person = Person( new clazz() );

Конечно, raw.type может содержать Person или 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()

Надеюсь, это поможет:)

1 голос
/ 17 июня 2009

Чтобы сохранить вещи в чистоте и избежать ошибок, я бы использовал отдельные объекты для выполнения обеих этих задач. Например, для обработки преобразования у вас может быть следующий объект:

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;
    }
}

Это разделение помогает поддерживать ваш код в чистоте, а также предоставляет простой способ работы с ним и управления им. Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...