Flex, pár drobností
Při studiu na nedávnou Flexovou certifikaci jsem se musel poměrně hodně hluboko ponořit do Flexové dokumantace. A to jak do reference ActionScriptu, tak do konceptů a architektury samotného Flexu Using Flex. Důvod byl jednoduchý — nedostatek praxe jsem musel nahradit porozuměním.
Protože se mi architektura Flexu líbíla, rád bych se k němu vrátil a pro ten případ si tady chci zaarchivoval pár věcí, které mne zaujaly.
Bidirectional binding
Pokud chci mít obousměrné datové propojení dvou komponent, mám k dispozici tři způsoby. Buď je vzájemně provázat jednosměrným bindingem:
<s:TextInput id="input1" text="{input2.text}"/>
<s:TextInput id="input2" text="{input1.text}"/>
Nebo na zdroji říct, že propojení je obousměrné pomocí znaku zavináče (@
):
<s:TextInput id="input1" text="@{input2.text}"/>
<s:TextInput id="input2"/>
Anebo použít tag <fx:Binding> s nastavenou twoWay
property:
<fx:Binding source="input1.text"
destination="input2.text"
twoWay="true"/>
Event flow
Flex je framework postavený mmj. na Even-driven architekturě. Události zde proto hrají jednu z ústředních rolí. Pokud je na nějakém komponentu spuštěna (triggered) událost, má Flex definovány tři fáze, během kterých zjišťuje, zda události naslouchají nějaký event listeneři:
- Capturing Phase probíhá od kořenového uzlu (root node) komponentového stromu až k rodičovskému uzlu cílového komponentu (target node). Na obrázku Application → Group → Panel. Flash Player na každém uzlu kontroluje, zda má na spuštěnou událost zaregistrovaný listener, pokud ano, listener zavolá.
- Targeting Phase zahrnuje pouze cílový/spouštěcí komponent (target node). Na komponentu jsou zavolány registrovaný listenery.
- Bubbling Phase probíhá od rodičovského uzlu cílového komponentu zpět ke kořenovému uzlu. Na obrázku Panel → Group → Application. Opět jsou zavolány registrované listenery.
Jak to všechno funguje ukazuje následující kód. V MXML je definován komponentový strom z obrázku (Application → Group →Panel → Button). Ve fázi inicializace (funkce initializeHandler
) jsou na komponenty navěšeny listenery, na každý dva — jeden pro fázi capturing, jeden pro fázi bubbling. Zbytek funkcí jsou event handlery, které vypisují text do debug konzole (metoda trace
).
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
initialize="initializeHandler(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
protected function clickHandler(event:MouseEvent):void {
trace("Button has been clicked.");
}
protected function groupEventHandler(event:Event):void {
trace("Event has been dispatched to: " + event.currentTarget);
}
protected function panelEventHandler(event:Event):void {
trace("Event has been dispatched to: + event.currentTarget);
}
protected function buttonEventHandler(event:Event):void {
trace("Event has been dispatched to: + event.currentTarget);
}
protected function initializeHandler(event:FlexEvent):void {
group.addEventListener(MouseEvent.CLICK,
groupEventHandler,
true);
group.addEventListener(MouseEvent.CLICK,
groupEventHandler);
panel.addEventListener(MouseEvent.CLICK,
panelEventHandler,
true);
panel.addEventListener(MouseEvent.CLICK,
panelEventHandler);
button.addEventListener(MouseEvent.CLICK,
buttonEventHandler,
true);
button.addEventListener(MouseEvent.CLICK,
buttonEventHandler);
}
]]>
</fx:Script>
<s:Group id="group">
<s:Panel id="panel" title="Panel">
<s:Button id="button"
label="Button Event"
click="clickHandler(event)"/>
</s:Panel>
</s:Group>
</s:Application>
Po kliknutí na tlačítko Button Event se na debug konzoli vypíše následující výpis (řádky jsou zalomeny). Jednotlivé barvy představují výše popsané fáze.
HTTPService
Pro zaslání HTTP requestu a příjem odpovědi na/z nějaké URL obsahuje Flex třídu HTTPService. Třída funfuje asynchronně — metodou send() se odešle request a události result se nastaví handler, který zpracuje response. Celé je to jednoduché a elegantní:
<fx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
protected function init():void {
categoryService.send();
}
protected function resultHandler(event:ResultEvent):void {
trace(event.result);
}
]]>
</fx:Script>
<fx:Declarations>
<s:HTTPService id="categoryService"
url="http://www.flexgrocer.com/category.xml"
resultFormat="e4x"
result="resultHandler(event)"/>
</fx:Declarations>