Лучший способ десериализации JSON - PullRequest
2 голосов
/ 05 марта 2010

Мне кажется, я установил, что в 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 к гибкому типу. Мой первый вопрос: верно ли мое предположение, и нет более красивого способа создания экземпляра модели с данными, содержащимися в json?

Мой второй вопрос, если так, то прежде чем я напишу свой собственный метод для этого, есть ли что-нибудь внутри flex api, которое будет принимать объект данных и смешивать его значения с моим экземпляром модели?

Приветствия

Chris

Ответы [ 2 ]

2 голосов
/ 05 марта 2010

подход, который я всегда использовал, оказался частью механизма сериализации AMF3 в ActionScript.

взглянем на IExternalizable и registerClassAlias ​​.

теперь я использую следующее:

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
}

и для декодера / кодера вы регистрируете псевдоним класса.

сериализация объекта работает следующим образом: *Декодирование 1015 *

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 голос
/ 05 марта 2010

Вы можете зациклить поле вашего 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...