Resolver problemas de mapeamento de VO’s entre o Flex 2 e PHP através de AMFPHP
Depois de várias horas a bater com a cabeça devido ao famoso “warning: unable to bind to property ‘titulo’ on class ‘Object’ (class is not an IEventDispatcher)” quando se usa Flash Remoting no Flex 2, cheguei finalmente à rídicula (mas lógica) solução. Para que outros não caiam na mesma armadilha que eu, fica aqui a explicação do problema e respectiva resolução.
O Flash Remoting permite mapear tipos de dados simples ou complexos entre o cliente o servidor. Assim, se tivermos a definição de um objecto que possui um: id:int; nome:String; data_de_nascimento:Date; do lado do cliente (Actionscript), e outro do lado do servidor (php) com a mesma estrutura, se utilizarmos Flash Remoting para trocar objectos deste género ele encarregar-se-á de reconhecer os tipos de dados e fazer os mapeamentos automaticamente. Aliás, este é o comportamento desejado em qualquer RPC.
Porém, quando combinamos AMF3 com AMFPHP 1.9 b2 é habitual surgir o famoso erro descrito acima. Quando isto acontece, devem ser verificados os seguintes critérios (para simplificar, vou chamar VO aos objectos trocados):
- O VO do lado do servidor deverá estar dentro de uma estrutura de pastas (ex.: org/riapt/vo/NoticiaVO.php) igual à do VO do lado do cliente;
- O VO do lado do servidor deverá possuir um atributo public $_explicitType= “org.riapt.vo.NoticiaVO” onde org.riapt.vo.NoticiaVO deverá corresponder à estrutura de pastas descrita anteriormente;
- O VO do lado do cliente deverá possuir a metadata RemoteClass(alias=”org.riapt.vo.NoticiaVO”) antes da definição da classe;
- Ambos os VOs devem ter a mesma estrutura (i.e. os mesmos nomes para os atributos e os mesmos tipos de dados)
- Se forem VO’s compostos por atributos de tipos de dados complexos (i.e. atributos cujo tipo de dados não é int, boolean, date ou string), esses atributos devem obedecer à regra descrita anteriormente (i.e. também eles devem ter uma estrutura idêntica e o mesmo tipo de dados)
- E finalmente… A definição do VO deverá ser (obviamente) compilada juntamente com a aplicação, tanto usando os parâmetros do compilador, como criando um “dummy” object só para obrigar à inclusão da definição desse VO (i.e. var dummyObject:NoticiaVO).
A razão da minha última guerra foi este último critério. Apesar de estar a receber NoticiaVO’s e a usar os dados recebidos em imensos locais na minha aplicação, em nenhum sítio precisei de importar o meu NoticiaVO. Porquê? Porque o meu NoticiaVO implementa um interface (ArtigoVO) que estou a usar para permitir Dependency Injection. Logo, os componentes que usam o NoticiaVO não precisam de saber que é um NoticiaVO, apenas têm que saber que esse VO cumpre o interface definido pelo ArtigoVO. E assim sendo, em nenhum local do meu código, em quase mil ficheiros estava uma referência a um NoticiaVO…
… resultando em horas de desespero a perceber porque é que a minha aplicação não conseguia mapear os objectos recebidos para NoticiaVO. Adicionei ao meu código a linha “var dummyObject:NoticiaVO” e os meus problemas ficaram resolvidos!
No Comments
Make A CommentNo comments yet.
Comments RSS Feed TrackBack URL
This entry was written by