Feb17th2008

Tutorial I : Componente Flex şi cod ActionScript

Platforma Flex este bazată pe funcţiile player-ului Flash 9 care gestionează aplicaţiile pe partea de client (ca o explicaţie suplimentară despre Flex), totodată furnizând interacţiunea cu JavaScript şi conţinut HTML. Faptul că player-ul Flash s-a impus foarte mult, la care se adaugă independenţa lui de platformă, ajută programatorul să economisească timp şi resurse necesare la testare şi debugging.

Aplicaţiile Flex sunt create utilizând două tipuri de fişiere: MXML şi ActionScript 3. Fişierele MXML sunt bazate pe standardul impus de XML, definind layout-ul interfeţei prin utilizarea tag-urilor, în special a celor care corespund elementelor vizibile (containere şi controale), dar şi a celor nereprezentate vizual: date, data binding (păstrarea legăturii între o componentă şi datele pe care aceasta le foloseşte) şi resurse în legătură cu serverul. Fişierele ActionScript 3 sunt scrise într-un limbaj de programare asemănător lui JavaScript (de altfel, există voci care afirmă că ActionScript 3 este, în fapt, JavaScript 2). De reţinut aspectul că limbajul ActionScript 3 este case sensitiv (variabilele, cuvintele cheie, clasele, metodele şi proprietăţile au nume diferite distinctiv de litere mari sau mici : myCombo nu este echivalent cu MYCoMBo).

Modelul Adobe - succesul tehnologiei acesteia - se bazează pe un set consistent de componente ce pot fi utilizate. Fiecărei componente îi corespunde un tag, iar fiecare tag este descris în framework printr-o clasă (descrisă bineinţeles într-un fişier ActionScript şi supunându-se regulilor de programare orientată pe obiecte). Folosindu-ne de conceptele de moştenire şi polimorfism aplicabile, putem extinde şi personaliza componentele în funcţie de necesităţile aplicaţiei pe care o construim.

Pentru a extinde o componentă Flex este suficient să dezvoltăm o subclasă a respectivei componente, (re)definind metodele şi proprietăţile de care avem nevoie pentru a obţine rezultatul dorit. Este bine de ştiut că toate containerele şi controalele Flex îşi moştenesc proprietăţile din clasa UIComponent, lucru de care ne putem folosi oricând ştiind ce anume oferă moştenitorilor această clasă.

În tutorialul de faţă, vom extinde componenta (controlul) ComboBox (mx.controls.ComboBox), presupunând că aţi trecut deja de aplicaţia Hello World şi că aveţi cunoştinţele minime necesare pentru a urmări logica şi a vă completa cunoştinţele.

Sintaxa generală pentru a extinde o componentă utilizând ActionScript 3, este "public class <clasă extinsă> extends <clasa moştenită>", unde clasa extinsă şi clasa moştenită se înlocuiesc după necesităţi cu numele claselor în cauză, în exemplul nostru public class cmbJudete extends ComboBox. Fişierul care conţine codul clasei extinse se va numi cmbJudete (atenţie, case-sensitive) la care se adaugă extensia .as, după caz .MXML - numele şi poziţia acestui fişier în sistemul de directoare al proiectului aplicaţiei modifică condiţiile din explicaţia referitoare la namespace.

Este de la sine înţeles că puteţi extinde componente şi utilizând fişiere MXML, diferenţa constând în maniera de a descrie metodele şi proprietăţile - deşi, în ultimă instanţă, rezultatul este acelaşi (făcându-se referire la acelaşi tip de meta-data, data-binding sau alte accesorii).

Pentru a putea folosi componenta extinsă creată, este necesar ca în cadrul aplicaţiei noastre, să declarăm namespace-ul respectivei componente, înainte de a o folosi - astfel încât să fuznizăm informaţii compilatorului despre locaţia în care se găseşte fişierul sursă. Cu siguranţă, aţi observat că toate aplicaţiile au cel puţin o declaraţie namespace <mx : Application xmlns : mx = "http://www.adobe.com/2006/mxml" /> care indică sursa (inclusiv natura sursei - dacă e text sau precompilată, ca în cazul componentelor native), ecosistemul componentelor Flex fiind astfel precedate de particula mx definită în tag-ul aplicaţiei.

Primul pas pe care-l vom face este acela de a defini clasa ActionScript care descrie componenta noastră:

  1. într-un proiect Flex nou, adăugăm subdirectorul ro, în care creăm subdirectorul flexug, în care creăm subdirectorul tutorial1.
  2. dacă folosiţi Flex Builder, selectaţi File » New » ActionScript Class. În vrăjitorul apărut, denumiţi pachetul (package) ro.flexug.tutorial1 şi clasa cmbJudete.as; indicaţi superclass ca fiind mx.controls.ComboBox
  3. codul generat de vrăjitor ar trebui să arate aşa:
Actionscript:
  1. package ro.flexug.tutorial1{
  2.  
  3. import mx.controls.ComboBox;
  4. public class cmbJudete extends ComboBox{
  5. public function cmbJudete():void{
  6. }
  7. }
  8. }

După cum bănuiţi, vrăjitorul a pregătit terenul pentru noi, declarând ce importăm, ce clasă moştenim şi a scris codul constructorului, clasa fiind declarată publică, astfel încât s-o putem folosi utilizând un tag MXML. Constructorul este metoda principală a unei clase, fiind prima metodă chemată imediat ce obiectul a fost creat. Particularitatea unui constructor constă în aceea că poartă acelaşi nume cu clasa pe care o "construieşte", nu poate întoarce valori (void întotdeauna) şi nu este moştenită.

Scopul nostru este să creăm un ComboBox modificat, care să conţină date: definim trei proprietăţi care conţin localităţi din judeţele Galaţi, Botoşani şi rezultatul concatenarii acestora. Aceste trei array-uri vor fi dataProvider pentru ComboBox-ul nostru, iar în faza de iniţializare, utilizatorul va decide care dintre valori să fie folosite. Pentru modificarea dataProvider-ului în funcţie de indicarea valorii, vom defini o metodă care stabileşte acest lucru în funcţie de un parametru de tip string (care poate lua valorile: toate, galati, botosani). Metadata-ul [Inspectable] este folosit pentru a descrie atributul ce schimba valorile dataProvider-ului. Acest metadata poate accepta mai mulţi parametri, printre care valoare implicită folosită în cazul getter/setter-ului, respectiv enumerarea valorilor pe care le poate lua acest atribut.

Metodele de tip getter/setter sunt modalităţi care permit schimbarea valorii unei proprietăţi private. Aceste metode sunt accesibile în afara clasei şi pot fi accesate prin numele proprietăţii, oferind posibilitatea de a crea proprietăţi cu funcţionalitate sofisticată, spre deosebire de proprietăţile publice clasice, care se pot accesa direct. Practic, dacă instanţa clasei s-ar numi jCmb, atunci jCmb.alegeJudet = 'toate' cheamă metoda care operează cu dataProvider-ul, totodată păstrând valoarea 'toate' în proprietatea privată a clasei numită 'judet'.

În urma celor prezentate, codul clasei noastre va arăta aşa:

Actionscript:
  1. package ro.flexug.tutorial1{
  2. import mx.controls.ComboBox;
  3.  
  4. public class cmbJudete extends ComboBox{
  5.  
  6. private var galati:Array = new Array("Galaţi","Barboşi","Tecuci", "Târgu Bujor", "Cuca");
  7. private var botosani:Array = new Array("Botoşani", "Dorohoi","Darabani" , "Brăieşti" , "Cucuteni","Dumeni" , "Broscăuţi" , "Leorda", "Rădăuţi-Prut", "Roma");
  8.  
  9. private var toateLocurile:Array = galati.concat(botosani);
  10.  
  11. [Inspectable(defaultValue="toate",enumeration=galati, botosani, toate)] private var judet:String = "toate";
  12.  
  13. public function cmbJudete():void{
  14. }
  15.  
  16. public function set alegeJudet(judetParam:String):void{
  17. judet = judetParam;
  18. if (judet == "galati"){
  19. this.dataProvider = galati;
  20. }else if (judet == "botosani" ){
  21. this.dataProvider = botosani;
  22. }else{
  23. this.dataProvider = toateLocurile;
  24. }
  25. }
  26.  
  27. [Bindable]
  28. public function get alegeJudet():String{
  29. return judet;
  30. }
  31.  
  32. }//sfarsit clasa
  33. } //sfarsit pachet

Componenta noastră este definită, dar este necesar să declarăm namespace-ul acesteia în cadrul aplicaţiei înainte de a o putea folosi:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:comp="ro.flexug.tutorial1.*">
</mx:Application>

După cum puteţi observa, namespace-ul indică structura de directoare anterior definită, astfel încât compilatorul să poată identifica sursa cu uşurinţă. Locaţia se închiei cu *, ceea ce indică ca puteţi defini şi alte componente în acelaşi director, cu condiţia să păstraţi acelaşi pachet - package (ro.flexug.tutorial1). Mai jos, puteţi observa utilizarea namespace-ului definit, <comp:cmbJudete id="jCmb" alegeJudet="toate" />

<mx:Application mlns:mx="http://www.adobe.com/2006/mxml" xmlns:comp="ro.flexug.tutorial1.*">
<mx:Panel title="Tutorial 1 - Componente si ActionScript" width="300" height="200">
<comp:cmbJudete id="jCmb" alegeJudet="toate" />
</mx:Panel>
</mx:Application>

Puteţi testa aplicaţia, sfârşind astfel walk through-ul al acestui tutorial.

Cu siguranţă vă veţi dori să extindenţi şi mai mult componenta creată. Iată o idee:

  1. în aplicaţie, adăugăm un grup de butoane radio, prin care să se facă selecţia dataProvider-ului componentei:
  2. <mx:RadioButtonGroup id="rgrup" itemClick="jCmb.schimbaJudet(event.currentTarget.selectedValue)"/>
    <mx:RadioButton groupName="rgrup" id="toate" value="toate" label="Toate" width="150"/>
    <mx:RadioButton groupName="rgrup" id="galati" value="galati" label="Galaţi" width="150"/>
    <mx:RadioButton groupName="rgrup" id="botosani" value="botosani" label="Botoşani" width="150"/>

  3. după cum puteţi observa, schimbaJudet nu este definit în componenta noastră. Mai mult decât atât, vorbim deja de evenimente - ca o introducere pentru următorul tutorial.
  4. Actionscript:
    1. [Bindable(event="schimbaJudetEvt")]
    2. public function schimbaJudet(judetParam:String):String{
    3. judet = judetParam;
    4. if (judet == "galati"){
    5. this.dataProvider = galati;
    6. }else if (judet == "botosani" ){
    7. this.dataProvider = botosani;
    8. }else{
    9. this.dataProvider = toateLocurile;}
    10. dispatchEvent(new Event("schimbaJudetEvt"));
    11. return judet;
    12. }

  5. în setter-ul lui alegeJudet se adaugă la sfârşitul acesteia, anunţarea evenimentului (schimbarea de dataProvider implicită, pentru o funcţionare corectă - corelare între componente) : dispatchEvent(new Event("schimbaJudetEvt"));
  6. de asemenea, getter-ul lui alegeJudet trebuie să dispună anunţarea evenimentului, prin adăugarea înainte de corpul metodei a [Bindable(event="schimbaJudetEvt")] - din acelaşi motiv de corelare între componente.
  7. se poate adăuga în cadrul Panel-ului şi eticheta <mx:Label text="Localităţile judeţului {jCmb.alegeJudet} sunt încărcate"/> pentru a verifica care dintre valori sunt încărcate şi a testa interacţiunea dintre componente.

Deşi aceste din urmă explicaţii fac referire la termeni neexplicaţi în cadrul acestui tutorial, cum sunt cei legaţi de evenimente şi de data - binding, ele sunt prezente aici pentru a vă deschide apetitul pentru mai multe noţiuni şi pentru a pregăti terenul următoarelor tutoriale.

0 Răspunsuri la “Tutorial I : Componente Flex şi cod ActionScript”


  1. Fără comentarii

Leave a Reply

Trebuie să fiţi autentificat pentru a publica un comentariu.