Creare actionscript Component
C’è una relazione tra gli MXML Components e quelli sviluppati con Actionscript. In fase di compilazione si riduce tutto ad una classe Actionscript. Perché allora a developer dovrebbe creare un Actionscript Component ? Questa scelta dipende ovviamente dagli obiettivi e di requisiti del progetto, ma ci sono alcune regole che possono aiutare lo sviluppatore in questa scelta. Partendo dal presupposto che qualunque cosa si voglia fare o programmare con un custom component, gli stessi risultati si possono ottenere sia con Actionscript component che con MXML Component. Di solito però se si debbono creare simple component che modificano il comportamento di un component di Flex esistente è più veloce creare un MXML Component.
Il caso di un ComboBox control a cui vanno aggiunte delle funzionalità o che deve essere personalizzato, definisce proprio lo scenario in cui è preferibile usare MXML Component. Nel caso in cui si debba creare un visual component estendendo la classe UIComponent, o creare un non visual component come può essere un custom formatter e validator, è preferibile usare un Actionscript component. In questa soluzione vedremo come creare un semplice Actionscript component, andando a creare e lavorare su una Actionscript class.
Cosa implica
Per creare un Actionscript Component si deve creare una classe Actionscript che conterrà sia gli elementi visuali che la parte di logica del nostro componente. Abbiamo già detto che tutti i Flex components sono implementati come class hierarchy in ActionScript, la quale contiene tutte le classi che definiscono le funzionalità di Flex 2. Vedi immagine 1.
I componenti visuali, quelli che quindi compaiono sullo schermo con una User Interface, derivano dalla classe UIComponent.
Per creare quindi un Actionscript component, la classe Actionscript dovrà estendere la UIComponent class. In questo modo tutte le proprietà, metodi ed eventi vengono ereditati (inherit).
Per estendere una classe in Actionscript basta usare la keyword “extend”:
package com
{
import mx.controls.DataGrid;
public class Chapter_2_Sol_3 extends DataGrid
{
public function Chapter_2_Sol_3()
{
}
}
}
Questa classe extends il DataGrid Control standard di Flex e permette di ereditare tutte le proprietà, metodi ed eventi di questo componente. Gli Actionscript component vengono poi invocati e referenziati all’interno dell’applicazione Flex come MXML tags.
Come realizzarlo
In questo esempio andremo ad estendere un ComboBox Control, andando ad inserire un valore all’interno del suo dataProvider. Comune a tutti i data-driven controls, la proprietà dataProvider è una serie di oggetti che contengono informazioni richieste da un component perchè possa essere popolato.
Quando si ha un comboBox e solitamente lo si popola con un dataProvider che magari viene associato ad un data binding a dei valori che sono il risultato di una chiamata remota. La maggior parte delle volte quindi il combo box non esporrà come prima voce il classico “Select a value ..”, che come buona norma di usabilità aiuta l’utente a capire che deve selezionare uno dei valori.
Andremo quindi a creare un Actionscript component che automaticamente inserirà questa Stringa come prima valore da visualizzare all’interno del combo box.
1. Apriamo il progetto Flex creato nel precedente esempio: Chapter_2_Flex_2_Components
2. Creiamo una nuova Actionscript class da File > New > Actionscript Class. Nella dialog window che compare, selezioniamo i seguenti valori nelle rispettive Input box:
Package: com
Name: Chapter_2_Sol_3
Superclass: mx.controls.ComboBox
Vedi immagine 1.
In questo modo abbiamo fatto creare automaticamente una Actiosncript class che estende la classe ComboBox e che quindi ne eredita tutte le proprietà, metodi ed eventi. Inoltre abbiamo fatto salvare la custom Actionscript class nella folder “com”, che è quella ce contiene i nostri custom component.
Il codice della classe è per ora il seguente:
package com
{
import mx.controls.ComboBox;
public class Chapter_2_Sol_3 extends ComboBox
{
public function Chapter_2_Sol_3()
{
}
}
}
Il metodo public Chapter_2_Sol_3() è il constructor della classe. Non dovete preoccuparvi di metterlo nel caso in cui non vi serve. In fase di compilazione infatti ci penserà Flex a crearlo. E’ comunque una best practise inserire sempre il constructor di una classe .
3. A questo punto possiamo andare ad aggiungere il codice al nostro Actionscript component, per settare un valore di default come primo valore che popolerà il dataProvider del ComboBox. Per fare ciò definiremo una variabile private con data type ArrayCollection, che verrà settata dai metodi getter and setter della classe:
package com
{
import mx.controls.ComboBox;
import mx.collections.ArrayCollection;
public class Chapter_2_Sol_3 extends ComboBox
{
private var _myDP:ArrayCollection;
public function set setMyDP(dataP:ArrayCollection):void
{
_myDP = dataP;
_myDP.addItemAt(“Select a value ...”, 0);
this.dataProvider = _myDP; }
public function get setMyDP():ArrayCollection
{
return _myDP;
}
public function Chapter_2_Sol_3()
{
}
}
}
Il metodo setter assegna alla private property _ myDP il valore che gli verrà passato come data provider dall’applicazione che richiamerà questo custom component. Usando il metodo addItemAt() della classe ArrayCollection, aggiungiamo sull’indice zero (l’ArrayCollection class is index zero based) una stringa, che sarà quello che comparirà sul ComboBox in fase di renderizzazione a video:
public function set setMyDP(dataP:ArrayCollection):void
{
_myDP = dataP;
_myDP.addItemAt(“Select a value ...”, 0);
this.dataProvider = _myDP; }
Creato il nostro Actionscript Component, possiamo andare a referenziarlo all’interno di un Application.
4. Create un nuovo MXML Application document from File > New > MXML application e assegnategli il nome Chapter_2_Sol_3_app.mxml. Questo sarà il nostro main appliction file che invocherà l’Actionscript Component. Aggiungiamo del codice all’applicazione andando prima di tutto a definire un custom namespace sul tag Application:
<?xml version=”1.0” encoding=”utf-8”?>
<mx:Application
xmlns:mx=”http://www.adobe.com/2006/mxml”
layout=”vertical”
xmlns:comp = “com.*”>
</mx:Application>
Il namespace “comp” punta al package “com” che contiene il nostro Actionscript component. Per poterlo invocare, proprio come abbiamo fatto per l’MXML Component, uso la tag notation.
5. Referenziamo la classe Actionscript con il nome del file senza l’estensione .as:
<?xml version=”1.0” encoding=”utf-8”?>
<mx:Application
xmlns:mx=”http://www.adobe.com/2006/mxml”
layout=”vertical”
xmlns:comp = “com.*”>
<comp:Chapter_2_Sol_3 id=”myCB” />
</mx:Application>
L’Actionscript component è stato invocato all’interno dell’applicazione. Adesso manca di passargli il data provider.
6. All’interno di un blocco Script, inseriamo e valorizziamo un variabile con data type ArrayCollection, che contiene i valori che andranno a popolare la custom combo box. Questa variabile verrà passata al custom component, che provvederà a svolgere le operazioni dichiarate all’interno del metodo setMyDP() :
<mx:Application
xmlns:mx=”http://www.adobe.com/2006/mxml”
layout=”vertical”
xmlns:comp = “com.*”>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
private var myAC:ArrayCollection = new ArrayCollection([“First Value”, “Second Value”,”Third Value”]);
]]>
</mx:Script>
<comp:Chapter_2_Sol_3 id=”myCB” setMyDP=”{myAC}” />
</mx:Application>
Salvate ed eseguite l'applicazione. Il risultato finale vedrà la custom combo box con il valore di partenza settato alla stringa definita nell'immagine 2
Expert’s Tips
Quando si sviluppano componenti che devono ritornare indietro dei dati al main application come best practise si dispatch an event dal componente con il metodo dispatchEvent(new Event(“myEvent”));.
Questo evento contiene i valori di ritorno che verranno quindi gestiti dagli event handlers dellamain application.
Possiamo inserire un Button all’interno dell’esempio precedente che cambia il valore del data provider del custom combo box, settando una nuova variabile ArrayCollection:
<mx:Application
xmlns:mx=”http://www.adobe.com/2006/mxml”
layout=”vertical”
xmlns:comp = “com.*”>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
private var myAC:ArrayCollection = new ArrayCollection([“First Value”, “Second Value”,”Third Value”]);
private var myAC_2:ArrayCollection = new ArrayCollection([“Hello”, “Goodbye”]);
]]>
</mx:Script>
<comp:Chapter_2_Sol_3 id=”myCB” setMyDP=”{myAC}” />
<mx:Button id=”my” label=”Change the Data Provider” click=”myCB.setMyDP = myAC_2” />
</mx:Application>
E’ stata quindi creata una private variable di tipo ArrayColelction che contiene due Strings:
private var myAC_2:ArrayCollection = new ArrayCollection([“Hello”, “Goodbye”]);
Sul click del Button the setter function setMyDP cambia il valore del data provider e fate partire l'evento:
<mx:Button id=”my” label=”Change the Data Provider” click=”myCB.setMyDP = myAC_2” />
All’interno dell’Actionscript Component eseguo il dispatch del custom event con il metodo dispatchEvent():
dispatchEvent(new Event(“changeDP”));
e rendo la funzione di getter bindable sul custom event creato:
[Bindable(event=”changeDP”)]
Questo è il codice completo dell’Actionscript class:
package com
{
import mx.controls.ComboBox;
import mx.collections.ArrayCollection;
import flash.events.Event;
public class Chapter_2_Sol_3 extends ComboBox
{
private var _myDP:ArrayCollection;
public function set setMyDP(dataP:ArrayCollection):void
{
_myDP = dataP;
_myDP.addItemAt(“Select a value ...”, 0);
this.dataProvider = _myDP;
dispatchEvent(new Event(“changeDP”));
}
[Bindable(event=”changeDP”)]
public function get setMyDP():ArrayCollection
{
return _myDP;
}
public function Chapter_2_Sol_3()
{
}
}
}



