Flex/AS3 – Truques e Dicas #1 – callLater

Flex/AS3 – Truques e Dicas #1 – callLater

Bem, depois de finalmente ter terminado um projecto enorme que tinha em mãos, que levou todo o meu tempo disponivel… venho finalmente anunciar que tenho mais um tempinho livre pro blog e voltarei a postar. Durante este projecto tive a hipotese de me deparar com bastantes problemas menos normais e mais profundos que envolvem um grande conhecimento da sandbox do flash e principalmente do as3.

 

Vou então iniciar uma série de tópicos falando de algumas dicas que são sem duvida muito uteis, principalmente na hora em que parece que tudo falha e na hora em que a resolução parece muito dificil.

 

#1 –  callLater()


Um dos problemas; Quanto por exemplo temos uma tabela que vai receber um dataProvider de, imaginem, 5.000 entradas e o seu dataprovider é atribuido via action script, ao fazermos:

[coolcode lang=”actionscript”] minhaTabela.dataProvider=meuArrayCollection;
[/coolcode]

A tabela é preenchida com as 5.000 linhas, que mesmo assim ainda demora algum tempo, talvez uns 2 segundos, e então se a tablea tiver items renders demora ainda mais, talvez uns 3/5 segundos dependendo do itemRender.

Continuando com o código eu quero que logo a seguir ao dataProvider ser atribuido, que a minha datagrid selecione a linha 2.700, para isso faço:
[coolcode] minhaTabela.dataProvider=meuArrayCollection;
minhaTabela.selectedIndex=2699;
minhaTabela.scrollToIndex(2699);
[/coolcode]

Este código simplesmente não vai funcionar. O problema que aqui se encontra, é que o dataprovider é atribuido, e no momento em que mando a datagrid selecionar o index 2699 este ainda não existe na tabela, porque o dataprovider ainda nao foi completamente inserido na tabela.  Aqui a alternativa mais rápida poderia passar por um evento na datagrid, como o dataChange, mas mesmo assim iriamos ter problemas com a criação dos dados e muito provavelmente teriamos uma dor de cabeça ao lidar com este problema. Uma forma  bem simples de o resolver é usar o callLater, neste caso fariamos por exemplo a função:
[coolcode lang=”actionscript”] private function onDPComplete():void {
minhaTabela.selectedIndex=2699;
minhaTabela.scrollToIndex(2699);
}
[/coolcode] E no nosso código usariamos apenas:
[coolcode] minhaTabela.dataProvider=meuArrayCollection;
callLater(onDPComplete);
[/coolcode]

E neste momento a função onDPComplete apenas será executada a seguir à próxima actualização do stage, ou seja, quando os dados tiverem sido atribuidos o ecra é actualizado e será executada a função para selecionar o index. Desta forma não teremos problemas porque quando a função for chamada os dados já estão todos “renderizados” pela tabela.

Este callLater pode enviar ou receber parametros, vejam o caso:

[coolcode] private function onDPComplete(linha:Number):void {
minhaTabela.selectedIndex=linha;
minhaTabela.scrollToIndex(linha);
}
[/coolcode]

Desta forma chamamos o callLater e passos or agumentos na forma de array [arg1, arg2, arg3] :

[coolcode] callLater(onDPComplete, [2699]);
[/coolcode]  

Um dos erros associados a este problema é:

 #1009: Cannot access a property or method of a null object reference. 

 

O callLater pode ainda ser mais especifico, como é associando a componentes visuais (UIComponent), neste exemplo como apenas diz respeito à tabela, poderiamos usar mais correctamente :

[coolcode] minhaTabela.callLater(onDPComplete, [2699]);
[/coolcode]  

Bom, desta forma podem resolver muitos problemas, principalmente quando tentam aceder a propriedades de elementos que ainda nao foram inicializados ou a sua criação feita (creationComplete).

Espero que seja util.

Abraço.


7 comments

add yours
  • janderson March 24, 2009

    callLater(), só isso, meu deu uma dor de cabeça daquelas quando enfrentei um problema parecido :( . Vlw pela Dica.

    abraços

  • Eguinaldo March 24, 2009

    Ta loko, Muito boa essa dica !
    isso vai ajudar num monte de coisas

  • William March 26, 2009

    Boa dica Mário!

    Como você solucionaria o problema do seu próprio exemplo sem usar o callLater()? Tem como? Só por curiosidade mesmo.

    Até

  • Mário Santos March 26, 2009

    Sim, poderiamos usaro o evento dataChange da tag mx:DataGrid … ou adicionando um collectionEvent ao dataprovider, ou até editando a class datagrid e fazer o truque de disparar um evento quando o dataProvider tiver forçado o refresh da datagrid (que é exactamente o que o callLater faz :P ).

    Mas bom, ainda bem que existe esse truque que poupa centenas de linhas em aplicações grandes.

    Abraço.

  • Ved March 27, 2009

    Mario, perfeito cara! Eu ja precisei disso e nao consegui resolver!

  • Nico April 12, 2009

    super
    je me prend la tête depuis deux heures à essayer de faire marcher un scrollToIndex() avec une List flash et grâce à toi j’ai compri que si cela ne marchait pas (sans erreur) c’est parce que le remplissage de la liste s’executait juste après dans le code!
    Un grand merci
    Maintenant je vais devoir trouver comment permettre aux utilisateurs de sélectionner plusieurs item sans utiliser le bouton shift ou ctrl ou pomme. Car mon programme doit fonctionner sur un écran tactile.
    En réécrivant la gestion du click de souris je devrais m’en sortir ^^

  • Mário Santos April 13, 2009

    Salut Nico.
    Tu peut trouver une solution aussi pour ton problème de plusieurs sélections en donnent a l’utilisateur un bouton(checkbox) qui quand activé, les “clicks” sur les items de la datagrid seront ajoutés au selectedIndexes, par example, si le checkbox “multi-selection” est selectioné, les indexes qui sont selectionnés sur le datagrid seront ajoutés au selectedIndexes… Si ça peut être une solution, je pense que c’est plus facile que réecriver la class de la datagrid.

Leave a Comment

Post