XML e E4X em Actionscript 3.0 - part 1
Acabei de deixar no meu Blog, um tutorial sobre XML e E4X em Actionscript 3.0 que gostaria de partilhar com a comunidade, pelo que para quem tiver interessado poderá visualizar aqui:
Acabei de deixar no meu Blog, um tutorial sobre XML e E4X em Actionscript 3.0 que gostaria de partilhar com a comunidade, pelo que para quem tiver interessado poderá visualizar aqui:
Depois de muito procurar e virar de “ponta-cabeça” o site da Adobe não consegui encontrar os downloads dos seminários que foram aqui notificados coisa que achei bem estranha já que na altura da subscrição desses mesmos seminários era-nos dito que seriam gravados e disponibilizados para download.
Depois de recorrer a vários motores de busca lá consegui começar a colher informações de onde se encontravam estes seminários… ainda não estão propriamente disponíveis para download, mas já podem ser vistos no “centro multimédia” Adobe Acrobat Connect.
Apenas não consegui encontrar 3 destes seminários, mas em contrapartida encontrei alguns também bem interessantes. Então deixo aqui a lista:
Extras:
Bem, já está aqui uma grande lista, mas com certeza que terá muita utilidade.
A Adobe está a disponibilizar gratuitamente cerca de 20 seminários online sobre Flex, Air, Flash Lite 3, ColdFusion, Blaze DS, Dreamweaver, etc. Para aceder aos seminários precisará somente de um computador ligado à Internet com o Flash Player instalado e de fazer uma pré-inscrição aqui nas sessões individuais que pretender assistir.
Quer assistir a uma sessão mas não tem disponibilidade à hora marcada? Não tem problema - a Adobe disponibilizará mais tarde as gravações dos seminários.
As sessões serão as seguintes:
Extending Web to the Desktop with AIR
Segunda, 24 de Março - 16:00 às 17:00
Getting Started with Flash Lite 3 and CS3
Segunda, 24 de Março - 18:00 às 19:00
What’s New in ColdFusion 8
Segunda, 24 de Março - 20:00 às 21:00
Building Rich Internet Applications with Flex 3
Segunda, 24 de Março - 23:00 às 00:00
Introduction to Adobe Blaze DS
Terça, 25 de Março - 16:00 às 17:00
Integrating Salesforce.com and Flex
Terça, 25 de Março - 18:00 às 19:00
Building AIR Applications with Flash CS3
Terça, 25 de Março - 20:00 às 21:00
Dreamweaver: Effective Standards-based Workflows for Ajax
Terça, 25 de Março - 23:00 às 00:00
Adobe AIR Local Data Storage Options With Emphasis on Using Embedded SQL Databases
Quarta, 26 de Março - 16:00 às 17:00
Flash Lite and Flex for Tourism
Quarta, 26 de Março - 18:00 às 19:00
ColdFusion Powered Rich Applications for the Internet and Desktop
Quarta, 26 de Março - 20:00 às 21:00
Flex and Java – Tying the Knot!
Quarta, 26 de Março - 23:00 às 00:00
Flex Data Services
Quinta, 27 de Março - 16:00 às 17:00
Adding Live Chat with ColdFusion & Adobe Blaze DS
Quinta, 27 de Março - 18:00 às 19:00
Blood from a Stone: Flash Game Optimization on Low-end mobile devices
Quinta, 27 de Março - 20:00 às 21:00
Flex Visual Data & Charting
Quinta, 27 de Março - 23:00 às 00:00
The Essential Guide to Dreamweaver CS3 with CSS, Ajax, and PHP
Sexta, 28 de Março - 16:00 às 17:00
ILOG Elixir: Your Remedy for Vibrant Data Visualization
Sexta, 28 de Março - 18:00 às 19:00
AIR Native Drag and Drop
Sexta, 28 de Março - 20:00 às 21:00
Flex Architecture
Sexta, 28 de Março - 23:00 às 00:00
Fiz a conversão das horas para GMT somando 7 horas ao US/Pacific. Se me tiver enganado, deixe um comentário neste post para que possa efectuar a correcção o quanto antes.
Clique aqui para fazer a inscrição ou para mais informações.
Pretendo com este post iniciar uma série de posts de best-practices de desenvolvimento em Actionscript 3.
Começo com um dos maiores erros que costumo ver, especialmente em antigos programadores Actionscript 2: a amaldiçoada utilização do parent (o antigo _parent) ou do stage (o antigo _root).
Este post aplica-se tanto a Flash CS3 como a Flex. O código está puramente em Actionscript 3, mas o raciocínio é exactamente o mesmo para MXML.
Imaginemos a seguinte imagem:
Temos o Stage. Dentro do Stage, temos um menu e duas secções: seccaoA e seccaoB. Dentro do menu temos dois botões: opcaoA e opcaoB. Ou seja:
Queremos que quando o utilizador clique na opcaoA, a seccaoA seja mostrada, e que aconteça o mesmo para a opcaoB e seccaoB.
O código, para os adeptos do “parent”, parece óbvio:
(Dentro do Menu):
// Construtor
public function Menu()
{
opcaoA.addEventListener(MouseEvent.CLICK, opcaoAClickHandler);
opcaoB.addEventListener(MouseEvent.CLICK, opcaoBClickHandler);
}
function opcaoAClickHander(ev:MouseEvent):void
{
parent.seccaoA.visible=true;
parent.seccaoB.visible=false;
}
function opcaoBClickHander(ev:MouseEvent):void
{
parent.seccaoA.visible=false;
parent.seccaoB.visible=true;
}
Aparentemente isto resolveria o problema de uma assentada só. Porém…
Infelizmente está 100% incorrecto utilizar o parent. A regra é simples: é *proibido* usá-lo. Surgiu um problema que obriga à utilização do parent? Repense! Leia este post, e veja como se resolve.
E obviamente perguntará: porque é que está incorrecto?
O seu menu está um espectáculo: é um dos preferidos na sua empresa tanto que o quer utilizar em vários projectos.
Entretanto aparece um novo projecto onde vai usar o menu. Porém foi outro elemento da equipa que fez a seccaoA e seccaoB, mas…. deu-lhes outros nomes. Chamou-lhes “seccao1″ e “seccao2″. E agora, que faz?
Primeira opção: mudar os nomes dados pelo seu colega (seccao1 e seccao2) para seccaoA e seccaoB. Big mistake: infelizmente o outro elemento da equipa tinha feito imenso código que usava intensivamente os nomes “seccao1″ e “seccao2″. E agora vai fazer o quê? Mexer no código dele? Não me parece…
Segunda opção: mudar no seu código onde está parent.seccaoA para parent.seccao1. Parece uma boa ideia dado o exemplo que fizemos aqui, mas se se tratasse um menu altamente complexo que usasse imensas vezes “parent.seccaoA”, seria lógico (e rápido) estar a mudar em todo o lado para seccao1 ?
Ok, é teimoso e estaria disposto a mudar o seu código todo… Porém, ao fazer isto, em vez de ter um menu que está a reutilizar entre projectos, na realidade acaba por estar a criar vários menus diferentes. Isto porque para cada projecto terá que mudar o código de cada menu de acordo com os nomes das secções. Ou seja, no fundo é um menu diferente com código diferente por projecto…
O seu projecto está feito e parece terminado. Porém, agora aparece o chefe a dizer “Ah e tal, vocês fizeram isto mal. Não quero a seccaoA dentro do Stage, mas sim dentro de um MovieClip chamado SectionContainer que tem uma borda e uns efeitos giros”. E lá vão vocês criar o SectionContainer, e colocar as secções lá dentro. Entretanto compilam e… Erro!
O código antigo do menu referia-se a parent.seccaoA. Porém, com a alteração, a seccaoA neste momento pode ser acedida assim: parent.sectionContainer.seccaoA. E com isto lá ter que ir mudar o seu código (e rezar para que o menu não seja complexo ao ponto de ter que mudar 23423423 linhas…).
A solução é relativamente simples, e passa por se cumprir uma regra também ela simples:
« Um componente/”MovieClip” nunca pode saber nada sobre quem o usa. Um componente/”MovieClip” só é responsável por si próprio »
Por outras palavras, se dentro do Menu está a fazer “parent.seccaoA”, quer dizer que o menu sabe que existe uma secção fora de si chamada seccaoA - sabe mais do que deveria saber.
Então como posso fazer: “quanto se clica na opcaoA, quero mostrar a seccaoA” se o menu não pode saber que há uma seccaoA ? Ora, o menu não tem que mudar para a seccaoA mas sim avisar quem o está a usar que está na altura de mudar para a seccaoA. Avisar como? Através de eventos!
O raciocínio passará a ser então:
Assim, o código correspondente:
(Dentro do Menu):
// Construtor
public function Menu()
{
opcaoA.addEventListener(MouseEvent.CLICK, opcaoAClickHandler);
opcaoB.addEventListener(MouseEvent.CLICK, opcaoBClickHandler);
}
function opcaoAClickHander(ev:MouseEvent):void
{
dispatchEvent(new Event("opcaoAClick"));
}
function opcaoBClickHander(ev:MouseEvent):void
{
dispatchEvent(new Event("opcaoBClick"));
}
(Dentro do Stage, que está associado a uma classe chamada Index):
// Construtor
public function Index()
{
menu.addEventListener("opcaoAClick", menuOpcaoAClickHandler);
menu.addEventListener("opcaoBClick", menuOpcaoBClickHandler);
}
function menuOpcaoAClickHandler(ev:MouseEvent):void
{
seccaoA.visible=true;
seccaoB.visible=false;
}
function menuOpcaoBClickHandler(ev:MouseEvent):void
{
seccaoA.visible=false;
seccaoB.visible=true;
}
Ou seja, se só o Stage é que sabe que existem secções, só o Stage é que pode mudar de secções. Então o menu simplesmente lança um aviso “olha, está na altura de mudar para a seccaoA”. O Stage apanha o aviso, e faz então o que é necessário para mostrar a secção correspondente.
Mais correcto ainda, seria criar um Custom Event, que possuiria uma String como propriedade pública onde seria colocado o nome da secção. Porém, isso fica para uma posterior lição.
Desta forma, o nosso menu já não sofre de problemas de reutilização nem de refactoring:
É de realçar que este raciocínio não deve ser aplicado só a menus, mas a TUDO. Vai usar o parent? Esqueça. Use o dispatchEvent!
No desenvolvimento de aplicações em Flex, mais cedo ou mais tarde surge a necessidade de se criar aplicações na nossa língua, e outras especificações tais como formatações de dígitos, datas e erros de validações. Muitas vezes a solução mais rápida é criar um pequeno Formatter e alterar o formato ou sobrepôr os valores por defeito de um Validator mas a forma mais correcta é utilizar o suporte de locale.
Eu e o João Saleiro decidimos facilitar o trabalho partilhando tradução de parte da framework para Português. Para poder compilar as aplicações de Flex em pt_PT terão de seguir os seguintes passos:
Para testar se a localização foi efectuada com sucesso, basta criar uma aplicação de teste com o seguinte código:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> <mx:DateChooser x="54" y="24"/> </mx:Application>
Os meses e os dias da semana deverão estar devidamente em Português.
O framework não foi traduzido na totalidade visto muitas das mensagens serem destinadas ao programador, mas fica aqui a lista do que foi traduzido :
Caso surja algum bug ou achem pertinente obter outras partes do framework traduzidas podem deixar aqui um comentário ou na mailing list.