Your SlideShare is downloading. ×
How To Flex - Fondamentali
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

How To Flex - Fondamentali

2,704

Published on

Sviluppare applicazioni con MXML …

Sviluppare applicazioni con MXML
Una semplice applicazione
Creare Flex Components
Creare MXML Components
XML Namespace personalizzati
Forms, FormItems e Validators
Gestire le Forms e i FormItem
Validare le forms con i Validator
Event Handling
Gestire gli Eventi
Capture, targeting, bubbling
Listener, Dispatching, sottoclassi MouseEvent KeyBoardEvent
Data Binding
Tipi di Binding
Monitorare il Data Binding: mx.binding.utils.ChangeWatcher
Usare il metadata tag [Bindable]
Binding a funzioni collegate ad eventi
FileReference
Caricare un file sul server con FileReference
Dataproviders e Collections
Dataproviders e Dataobjects
ArrayCollection, XMLList, XMLListCollection
Sort e Filter
Datagrids, AdvancedDatagrids, TreeView
Usare la DataGrid e AdvancedDatagrids
Usare le Treeview
Estendere le Datagrids: ItemRenderer e ItemEditor
Remote Procedure Call: le classi HTTPService e WebService
URLRequest e HTTPService
WebService
RemoteObject e RemoteClass

Published in: Technology, Education
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,704
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
0
Comments
0
Likes
3
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Rich Internet Application with Adobe Flex 3
  • 2. Agenda - 1 Sviluppare applicazioni con • Una semplice applicazione MXML Creare Flex • Creare MXML Components • XML Namespace personalizzati Components Forms, FormItems e • Gestire le Forms e i FormItem • Validare le forms con i Validator Validators • Gestire gli Eventi Event Handling • Capture, targeting, bubbling • Listener, Dispatching, sottoclassi MouseEvent KeyBoardEvent • Tipi di Binding • Monitorare il Data Binding: mx.binding.utils.ChangeWatcher Data Binding • Usare il metadata tag [Bindable] • Binding a funzioni collegate ad eventi
  • 3. Agenda - 2 • Caricare un file sul server con FileReference FileReference • Dataproviders e Dataobjects Dataproviders e • ArrayCollection, XMLList, XMLListCollection Collections • Sort e Filter • Usare la DataGrid e AdvancedDatagrids Datagrids, • Usare le Treeview AdvancedDatagrids, • Estendere le Datagrids: ItemRenderer e ItemEditor TreeView Remote Procedure • URLRequest e HTTPService Call: le classi • WebService HTTPService e • RemoteObject e RemoteClass WebService
  • 4. ActionScript 3 •I tag MXML servono per dichiarare: •Containers •Controls •Effects •Formatters •Validators •Web services • ecc ecc necessari al funzionamento dell‘applicazione •MXML non è appropriato per descrivere il flusso applicativo alla pressione di un tasto da parte dell‘utente •ActionScript è un linguaggio procedurale ad oggetti •ActionScript può essere mescolato a MXML in molti modi (es. event listener, tag <mx:Script>, file esterni)
  • 5. Creare Flex Components
  • 6. Creare MXML Component •Si definiscono sotto forma di file MXML e si utilizzano come custom tag in altri file •Incapsulano ed estendono i componenti già esistenti •Esempio: combobox custom pre-popolata <!-- mxml/containers/boxes/MyComboBox.mxml --> <!-- mxml/CustomMXMLComponent.mxml --> <mx:VBox <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot;> xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot; <mx:ComboBox > xmlns:MyComps=quot;containers.boxes.*quot;> <mx:dataProvider> <mx:Panel title=quot;My Applicationquot; <mx:String>Dogs</mx:String> paddingTop=quot;10quot; <mx:String>Cats</mx:String> paddingBottom=quot;10quot; <mx:String>Mice</mx:String> paddingLeft=quot;10quot; </mx:dataProvider> paddingRight=quot;10quot; </mx:ComboBox> > </mx:VBox> <MyComps:MyComboBox/> </mx:Panel> </mx:Application>
  • 7. XML Namespace personalizzati •Permettono di utilizzare custom tags non definiti nel namespace MXML <?xml version=quot;1.0quot;?> <!-- mxml/XMLNamespaces.mxml --> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot; xmlns:MyComps=quot;containers.boxes.*quot; > Può essere una subdirectory <mx:Panel title=quot;My Applicationquot; dell‘applicazione oppure una paddingTop=quot;10quot; subdirectory di quelle indicate nel file paddingBottom=quot;10quot; paddingLeft=quot;10quot; flex-config.xml, con precedenza a paddingRight=quot;10quot; quella dell‘applicazione > <MyComps:CustomBox/> </mx:Panel> </mx:Application>
  • 8. Forms, FormItems e Validators
  • 9. Forms e FormItems • Gli oggetti Forms permettono di gestire comodamente una serie di campi labelinput • L‘oggetto Form contiene n oggetti FormItems che a loro volta contengono l‘elemento di input specializzato dall‘attributo label del FormItem <mx:Form id=quot;formquot; x=quot;10quot; y=quot;10quot; width=quot;319quot; height=quot;90%quot;> <mx:FormItem label=quot;Name:quot; id=quot;lblNamequot; required=quot;truequot;> <mx:TextInput id=quot;txtNamequot;/> </mx:FormItem> <mx:FormItem label=quot;Description:quot;> <mx:TextArea id=quot;txtDescriptionquot;/> </mx:FormItem> <mx:FormItem label=quot;Phone Number:quot; required=quot;truequot;> <mx:TextInput id=quot;txtNumberquot;/> </mx:FormItem> <mx:FormItem label=quot;Date:quot;> <mx:DateChooser id=quot;ctlCalendarquot; showToday=quot;truequot;/> </mx:FormItem> <mx:FormItem> <mx:Button label=quot;Savequot; id=quot;btnSavequot; click=quot;save()quot;/> </mx:FormItem> </mx:Form>
  • 10. Validators • L‘oggetto Validator permette di validare velocemente gli elementi di input della Application • La classe Validator è la base class per tutti le sottoclassi del package mx.validators • Esistono vari tipi di validators già pronti in Flex: es. CurrencyValidator, DateValidator, CreditCardValidator, EmailValidator • Si possono creare nuovi custom Validators estendendo la classe Validator <mx:Validator id=quot;reqValidatorquot; source=quot;{txtName}quot; property=quot;textquot; required=quot;truequot; requiredFieldError=quot;Questo campo è obbligatorioquot; /> <mx:PhoneNumberValidator id=quot;phValidatorquot; source=quot;{txtNumber}quot; property=quot;textquot; required=quot;truequot; requiredFieldError=quot;Il numero di telefono è sbagliatoquot; />
  • 11. Data Binding
  • 12. Data Binding in Flex -1 3 tipi Posso utilizzare •MXML con la sintassi { } funzioni ActionScript <?xml version=quot;1.0quot;?> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot;> <mx:TextInput id=quot;myTIquot; text=quot;Enter text herequot;/> <mx:Text id=quot;myTextquot; text=quot;{myTI.text.toUpperCase()}quot;/> </mx:Application> •Separa la view •MXML con il tag <mx:Binding> dalla source <?xml version=quot;1.0quot;?> •Possibilità di <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot;> <mx:TextInput id=quot;myTIquot;/> binding multiplo <mx:Text id=quot;myTextquot;/> dalla stessa <mx:Text id=quot;myText2quot;/> source <mx:Binding source=quot;myTI.textquot; destination=quot;myText.textquot;/> <mx:Binding source=quot;myTI.textquot; destination=quot;myText2.textquot;/> </mx:Application>
  • 13. Data Binding in Flex - 2 • ActionScript con il metodo BindingUtils <?xml version=quot;1.0quot;?> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot;> <mx:Script> <![CDATA[ import mx.binding.utils.*; public function initBindingHandler():void { BindingUtils.bindProperty (myText, quot;textquot;, myTI, quot;textquot;); } ]]> </mx:Script> <mx:TextInput id=quot;myTIquot;/> <mx:Text id=quot;myTextquot; preinitialize=quot;initBindingHandler();quot;/> </mx:Application>
  • 14. Quando viene eseguito il Data Binding? 1. Quando la sorgente dati viene modificata 2. Sempre all‘avvio dell‘applicazione quando il controllo sorgente lancia l‘evento initialize
  • 15. Monitorare il Data Binding: mx.binding.utils.ChangeWatcher <?xml version=quot;1.0quot;?> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot; initialize=quot;initWatcher();quot;> <mx:Script> <![CDATA[ import mx.binding.utils.*; myWatcher.unwatch() import mx.events.FlexEvent; rimuove il watcher import mx.events.PropertyChangeEvent; public var myWatcher:ChangeWatcher; public function initWatcher():void { ChangeWatcher.watch(textarea, quot;textquot;, watcherListener); } public function watcherListener(event:Event):void { myTA1.text=quot;binding occurredquot;; } ]]> </mx:Script> <mx:TextInput id=quot;textinputquot; text=“Textbox sorgente datiquot;/> <mx:TextArea id=quot;textareaquot; text=quot;{textinput.text}quot;/> <mx:TextArea id=quot;myTA1quot;/> </mx:Application>
  • 16. Usare il metadata tag [Bindable] Serve per rendere sorgente dati una property. Due sintassi: 1. [Bindable] 2. [Bindable(event=quot;eventnamequot;)] Nel primo caso Flex crea automaticamente un evento propertyChange che verrà generato ogni qualvolta la property cambia valore per notificare i controlli bounded dell‘avvenuto cambiamento. <?xml version=quot;1.0quot;?> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot;> <mx:Script> <![CDATA[ [Bindable] public var maxFontSize:Number = 15; ]]> </mx:Script> <mx:Text text=quot;{maxFontSize}quot;/> <mx:Button click=quot;maxFontSize=20;quot;/> </mx:Application>
  • 17. Binding a funzioni collegate ad eventi <?xml version=quot;1.0quot;?> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot;> <mx:Script> <![CDATA[ import flash.events.Event; [Bindable(event=quot;myFlagChangedquot;)] private function isEnabled():String { if (myFlag) return 'true'; else return 'false'; } private var _myFlag:Boolean = false; public function set myFlag(value:Boolean):void { _myFlag = value; dispatchEvent(new Event(quot;myFlagChangedquot;)); } public function get myFlag():Boolean { return _myFlag; } ]]> </mx:Script> <mx:TextArea id=quot;myTAquot; text=quot;{isEnabled()}quot;/> <mx:Button label=quot;Clear MyFlagquot; click=quot;myFlag=false;quot;/> <mx:Button label=quot;Set MyFlagquot; click=quot;myFlag=true;quot;/> </mx:Application>
  • 18. Upload Files
  • 19. Caricare un file sul server con FileReference • Per effettuare un upload di un file tramite il cliente Flex si usa la classe FileReference o FileReferenceList • Lato server deve essere presente un endpoint che gestisca la scrittura sul file system remoto • Il file da caricare viene inviato alla pagina lato server in post in una form multipart e l‘upload viene gestito come un normale upload manuale Var fileRef:FileReference = new FileReference(); fileRef.addEventListener(Event.SELECT, fileSelected); fileRef.addEventListener(ProgressEvent.PROGRESS, notifyProgress); fileRef.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, uploadComplete); var urlReq:URLRequest = new URLRequest(uploadURL); fileRef.upload(urlReq, uploadDataFieldName, false);
  • 20. Event handling
  • 21. Gestire gli eventi in Flex •Gli eventi di Flex sono basati sul W3 - DOM Level 3 •Interfacce base di DOM lev.3 •Event •CustomEvent •EventTarget •EventListener •EventException •EventExceptionCode •Event types di DOM lev.3 •UIEvent •TextEvent •KeyboardEvent •MouseEvent •MouseMultiWheelEvent •MouseWheelEvent •MutationEvent •MutationNameEvent
  • 22. Le tre fasi Durante la fase di Capture, Flash Player valuta ogni elemento parent Application dell‘oggetto per determinare se abbia un listener associato. Gli 1 - Capture eventuali event listener trovati 3 vengono eseguiti prima che Panel Bubbling l‘evento raggiunga il target (button) Nella fase di Target, Flex invoca Title l‘event handler senza valutare altri Window nodi della display list 2 - Target Nella fase di Bubbling, viene Button ripetuta la valutazione effettuata durante il Capture ma in ordine inverso
  • 23. La classe flash.events.Event •E‘ una classe ActionScript con proprietà che descrivono l‘evento generato •L‘oggetto Event viene generato automaticamente ogni qual volta un evento viene gestito •Solo un oggetto Event viene generato durante le fasi di capturing e bubbling; Flex cambia il valore dell‘oggetto Event muovendosi nella gerarchia della display list
  • 24. Utilizzare gli eventi <?xml version=quot;1.0quot;?> <!-- events/SimpleEventHandler.mxml --> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot; creationComplete=quot;initApp();quot;> <mx:Script><![CDATA[ import mx.controls.Alert; private function initApp():void { b1.addEventListener(MouseEvent.CLICK, myEventHandler); } private function myEventHandler(event:Event):void { Alert.show(quot;An event of type 'quot; + event.type + quot;' occurred.quot;); } ]]></mx:Script> Posso utilizzare <mx:Button id=quot;b1quot; label=quot;Click Mequot;/> l‘oggetto Event </mx:Application> all‘interno dell‘handler
  • 25. Utilizzare gli eventi… senza addEventListener() <?xml version=quot;1.0quot;?> <!-- events/SimplerEventHandler.mxml --> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot;> <mx:Script><![CDATA[ import mx.controls.Alert; private function myEventHandler(event:Event):void { Alert.show(quot;An event occurred.quot;); } ]]></mx:Script> <mx:Button id=quot;b1quot; label=quot;Click Mequot; click=quot;myEventHandler(event)quot;/> </mx:Application> N.B. Con questa modalità non si può utilizzare la removeEventHandler
  • 26. Il metodo addEventListener componentInstance.addEventListener( event_type:String, event_listener:Function, use_capture:Boolean, priority:int, weakRef:Boolean) event_type : può essere una stringa (―mouseOut‖) oppure una costante (MouseEvent.MOUSE_OUT - preferito) event_listener : è il nome della funzione che gestirà l‘evento use_capture: se true, il listener sarà attivo durante la fase di capture priority: per specificare la priorità dell‘event listener rispetto agli altri eventualmente definiti sull‘evento weakRef: se false impedisce l‘uso del garbage collector sull‘event listener
  • 27. Esempio di addEventListener multiplo con priorità <?xml version=quot;1.0quot;?> <!-- events/CallingAddEventListenerInline.mxml --> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot;> <mx:Script><![CDATA[ import mx.controls.Alert; private function myClickHandler(event:Event):void { Alert.show(quot;PRIORITY 1: The button was clicked.quot;); } private function myClickHandler2(event:Event):void { Alert.show(quot;PRIORITY 2: The button was clicked.quot;); Posso utilizzare } addEventListener() da MXML usando la ]]></mx:Script> proprietà ―initialize‖ <mx:Button id='b1' label=quot;Click Mequot; initialize='b1.addEventListener(MouseEvent.CLICK, myClickHandler, false, 1); b1.addEventListener(MouseEvent.CLICK, myClickHandler2, false, 2);' /> </mx:Application>
  • 28. Il metodo removeEventListener componentInstance.removeEventListener( event_type:String, listener_function:Function, use_capture:Boolean ) event_type, event_listener : come per la addEventListener() use_capture: per ascoltare gli eventi durante tutte le fasi occorre usare la addEventListener() due volte, una con use_capture=true, l‘altra con use_capture=false. Pertanto, anche in fase di rimozione, andrà chiamata due volte la removeEventListener
  • 29. Creare una classe per l‘event handling package { // Empty package. import flash.events.Event; import mx.controls.Alert; public class MyEventHandler { public function MyEventHandler() { // Empty constructor. } public function handleAllEvents(event:Event):void { Alert.show(quot;Some event happened.quot;); } } } <?xml version=quot;1.0quot;?> <!-- events/CustomHandler.mxml --> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot; initialize=quot;createHandler()quot;> <mx:Script><![CDATA[ private var myListener:MyEventHandler = new MyEventHandler(); private function createHandler():void { b1.addEventListener(MouseEvent.CLICK, myListener.handleAllEvents); } ]]></mx:Script> <mx:Button label=quot;Submitquot; id=quot;b1quot;/> </mx:Application>
  • 30. Singolo listener per più componenti <?xml version=quot;1.0quot;?> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot; creationComplete=quot;createHandlers(event)quot;> <mx:Script><![CDATA[ import mx.controls.Alert; public function createHandlers(e:Event):void { b1.addEventListener(MouseEvent.CLICK, submitForm); b2.addEventListener(MouseEvent.CLICK, submitForm); } private function submitForm(e:Event):void { // Handle event here. Alert.show(quot;Current Target: quot; + e.currentTarget.id); } ]]></mx:Script> <mx:Button id=quot;b1quot; label=quot;Click Mequot;/> <mx:Button id=quot;b2quot; label=quot;Click Me, Tooquot;/> </mx:Application>
  • 31. Parametri addizionali negli event handler •La addEventListener accetta soltanto un parametro per cui dev’essere la listener_function a richiamare la funzione con più parametri • Usando la dichiarazione inline da MXML è possibile un numero a piacere di parametri <?xml version=quot;1.0quot;?> <!-- events/MultipleHandlerParametersInline.mxml --> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot;> <mx:Script><![CDATA[ public function runMove(dir:String, e:Event):void { …… } ]]></mx:Script> <mx:Button id=quot;b1quot; label=quot;Upquot; click='runMove(quot;upquot;,event);' width=quot;75quot; /> …… </mx:Application>
  • 32. Dispatching manuale degli eventi <?xml version=quot;1.0quot;?> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot; initialize=quot;createListener(event);quot;> Occorre creare un <mx:Script><![CDATA[ nuovo oggetto Event import mx.controls.Alert; private function createListener(e:Event):void { b1.addEventListener(MouseEvent.MOUSE_OVER, myEventHandler); b1.addEventListener(MouseEvent.CLICK, myClickHandler); } private function myEventHandler(e:Event):void { var result:Boolean = b1.dispatchEvent(new MouseEvent(MouseEvent.CLICK, true,false)); } private function myClickHandler(e:Event):void { Alert.show(quot;The event dispatched by the MOUSE_OVER was of type 'quot; + e.type + '.quot;); } ]]></mx:Script> <mx:Button id=quot;b1quot; label=quot;Click Mequot;/> </mx:Application> Si può usare anche l’inline MXML <mx:Button id=quot;b1quot; label=quot;Click Mequot; mouseOver=quot;b1.dispatchEvent(new MouseEvent(MouseEvent.CLICK, true, false));quot; />
  • 33. Trasformare un click in un doubleClick con lo Shift premuto <?xml version=quot;1.0quot;?> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot; creationComplete=quot;addListeners()quot;> <mx:Script><![CDATA[ private function customLogEvent(e:MouseEvent):void { l1.text = String(e.currentTarget.id); l2.text = String(e.type); l3.text = String(e.shiftKey); // Remove current listener to avoid recursion. e.currentTarget.removeEventListener(quot;doubleClickquot;, customLogEvent); } private function handleEvent(e:MouseEvent):void { // Add new handler for custom event about to be dispatched. e.currentTarget.addEventListener(quot;doubleClickquot;, customLogEvent); // Create new event object. var mev:MouseEvent = new MouseEvent(quot;doubleClickquot;); // Customize event object. mev.shiftKey = true; // Dispatch custom event. e.currentTarget.dispatchEvent(mev); } private function addListeners():void { b1.addEventListener(quot;clickquot;,handleEvent); b2.addEventListener(quot;clickquot;,handleEvent); } ]]></mx:Script>
  • 34. Oggetto Event: proprietà currentTarget e target currentTarget contiene il nodo corrente nella lista degli event handler target si riferisce sempre al dispatcher dell‘evento (non necessariamente l‘oggetto a cui è associato un event listener, es. un suo subcomponente come l‘UITextField di un Button)
  • 35. Oggetto Event: identificare la fase dell‘evento •La proprietà eventPhase dell‘oggetto Event contiene la fase corrente e può valere: •1 — Capturing phase (CAPTURING_PHASE) •2 — Targeting phase (AT_TARGET) •3 — Bubbling phase (BUBBLING_PHASE) •Un esempio di come identificare la fase all‘interno dell‘event handler: <?xml version=quot;1.0quot;?> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot;> <mx:Script><![CDATA[ import mx.controls.Alert; private function showInfo(e:MouseEvent):void { Alert.show(quot;Phase: quot; + e.eventPhase + quot;nquot; +quot;Current Target: quot; + e.currentTarget.id); } ]]></mx:Script> <mx:Button id=quot;b1quot; label=quot;Click Mequot; click=quot;showInfo(event)quot; /> </mx:Application>
  • 36. Oggetto Event: fermare la propagazione •Durante ogni fase è possibile fermare la propagazione dell‘evento utilizzando i seguenti metodi dell‘oggetto Event: •stopPropagation (non valuta il prossimo nodo ma esegue gli event handler trovati per il nodo corrente) •stopImmediatePropagation (non valuta il prossimo nodo e NON esegue gli altri event handler)
  • 37. Oggetto Event: le sottoclassi MouseEvent e KeyboardEvent •Usando la sottoclasse opportuna per un oggetto, si evita di dover eseguire il cast dell‘argomento Event dell‘event handler •Le sottoclassi espongono delle proprietà più specifiche •Si può definire un handler globale per gli eventi Keyboard <?xml version=quot;1.0quot;?> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot; creationComplete=quot;initApp();quot;> <mx:Script><![CDATA[ private function initApp():void { application.addEventListener(KeyboardEvent.KEY_UP, keyHandler); } private function keyHandler(event:KeyboardEvent):void { t1.text = event.keyCode + quot;/quot; + event.charCode; } ]]></mx:Script> <mx:TextInput id=quot;myTextInputquot;/> <mx:Text id=quot;t1quot;/> </mx:Application>
  • 38. MouseEvent e KeyboardEvent: qualche nota •La classe KeyboardEvent espone le proprietà keyCode (codice numerico del tasto) e charCode (codice carattere del tasto, relativo al character set) •Definendo un handler per il keyUp e il keyDown sia per un controllo che per il suo container, l‘evento keyboard sarà generato per entrambi a causa del bubbling. La proprietà target dell‘evento rimarrà costante mentre varierà la currentTarget in base al nodo esaminato dalla fase di bubbling •La classe MouseEvent (e le sue sottoclassi) espongono le seguenti proprietà che permettono di determinare l‘eventuale pressione dei tasti speciali durante l‘evento del mouse: •altKey •ctrlKey •shiftKey
  • 39. Data providers e Collections
  • 40. Le Collection • Le Collections sono oggetti che uniformano l‘accesso e la definizione dei dati contenuti negli oggetti data source come Array e XMLList • Le Collections creano un livello di astrazione tra i componenti Flex e i dati che li popolano • Garantiscono l‘update del controllo in caso di cambiamento dei dati sottostanti • Forniscono meccanismi di paging per dati che richiedano tempo per il download • Permettono di filtrare ed ordinare i dati sottostanti • Utilizzano le seguenti interfacce: •IList (basata sull‘indice con cui sono inseriti fisicamente gli oggetti nella collezione) •ICollectionView (permette sort e filter; espone un oggetto IViewCursor che permette di scorrere bidirezionalmente la collezione, di effettuare ricerche, salvare bookmark e rimuovere/inserire item)
  • 41. Il package mx.collections Classe Descrizione ArrayCollection Collezione standard per lavorare con gli array; implementa sia IList che ICollectionView XMLListCollection Collezione per gli oggetti XMLList; implementa sia IList che ICollectionView oltre ad un subset dei metodi di XMLList Rappresenta la posizione di un view cursor all‘interno della collezione CursorBookmark Necessarie per l‘ordinamento Sort / SortField ItemResponder Gestisce i data source remoti ListCollectionView Classe da cui derivano ArrayCollection e XMLListCollection Grouping Definisce i campi da utilizzare per raggruppare i dati e visualizzarli nella AdvancedDataGrid GroupingCollection Permette di creare dati raggruppati a partire da dati flat GroupingField Definisce il singolo campo di raggruppamento HierarchicalCollectionView Espone una vista gerarchica a partire da una collezione standard HierarchicalCollectionViewCursor Permette di definire un cursore sulla vista gerarchica HierarchicalData Contiene dati già strutturati gerarchicamente nella forma parent-child Rappresenta la riga ―summary‖ dell‘AdvancedDataGrid SummaryRow SummaryField Rappresenta il singolo campo della SummaryRow Mantiene le informazioni ―summary‖ per dei dati raggruppati SummaryObject
  • 42. Data objects •Espongono la proprietà dataProvider •ButtonBar •ColorPicker •ComboBox •DataGrid •DateField List-based data objects •HorizontalList •LinkBar •List •Repeater •TabBar •TileList •ToggleButtonBar •Tree •Menu Hierarchical data objects •MenuBar •PopUpMenuButton •E‘ possibile utilizzare array di stringhe o oggetti come provider ma è preferibile utilizzare le collections (ArrayCollection, XMLListCollection, custom collection) perchè garantiscono la notifica di cambiamenti nei dati e permettono il sorting e il filtering
  • 43. ArrayCollection <?xml version=quot;1.0quot;?> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot;> <mx:ComboBox id=quot;myCBquot;> <mx:ArrayCollection id=quot;stateArrayquot;> <mx:Object label=quot;ALquot; data=quot;Montgomeryquot;/> <mx:Object label=quot;AKquot; data=quot;Juneauquot;/> <mx:Object label=quot;ARquot; data=quot;Little Rockquot;/> </mx:ArrayCollection> </mx:ComboBox> </mx:Application> Sfrutto le default property dataProvider dell‘oggetto ComboBox e source dell‘oggetto ArrayCollection
  • 44. ArrayCollection con ActionScript (inline MXML) <?xml version=quot;1.0quot;?> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot; initialize=quot;initData()quot;> <mx:Script> <![CDATA[ import mx.collections.*; [Bindable] public var stateArray:ArrayCollection; public function initData():void { stateArray=new ArrayCollection( [{label:quot;ALquot;, data:quot;Montgomeryquot;}, {label:quot;AKquot;, data:quot;Juneauquot;}, {label:quot;ARquot;, data:quot;Little Rockquot;}]); } ]]> </mx:Script> <mx:ComboBox id=quot;myComboBoxquot; dataProvider=quot;{stateArray}quot;/> <mx:Button label=quot;Add AZ― click=quot;stateArray.addItem({'label':'AZ', 'data':'Phoenix'});quot;/> </mx:Application>
  • 45. ArrayCollection con ActionScript <?xml version=quot;1.0quot;?> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot; initialize=quot;initData();quot;> <mx:Script> <![CDATA[ import mx.collections.ArrayCollection; [Bindable] private var DGArray:ArrayCollection = new ArrayCollection([ {Artist:'Pavement', Album:'Slanted and Enchanted', Price:11.99}, {Artist:'Pavement', Album:'Brighten the Corners', Price:11.99}]); // Initialize initDG ArrayCollection variable from the ArrayCollection. public function initData():void { myGrid.dataProvider = DGArray; validateNow() serve per sincronizzare myGrid.validateNow(); tutte le proprietà dell‘oggetto, compreso il myGrid.selectedIndex=1; } databind, evitando che la selectedIndex ]]> vada in errore. </mx:Script> Attenzione alle performance! <mx:DataGrid id=quot;myGridquot;> <mx:columns> <mx:DataGridColumn dataField=quot;Albumquot;/> <mx:DataGridColumn dataField=quot;Pricequot;/> </mx:columns> </mx:DataGrid> </mx:Application>
  • 46. Ordinamento di un‘ArrayCollection <!-- dpcontrolsSimpleDP.mxml --> initialize=quot;sortAC()quot;> <mx:Script> <![CDATA[ import mx.collections.*; public function sortAC():void { var sortA:Sort = new Sort(); sortA.fields=[new SortField(quot;labelquot;)]; myAC.sort=sortA; myAC.refresh(); } public function addItemToMyAC():void { myAC.addItem({label:quot;MDquot;, data:quot;Annapolisquot;}); } ]]> </mx:Script> <mx:ArrayCollection id=quot;myACquot;> <mx:Array id=quot;myArrayquot;> <mx:Object label=quot;MIquot; data=quot;Lansingquot;/> <mx:Object label=quot;MOquot; data=quot;Jefferson Cityquot;/> <mx:Object label=quot;MAquot; data=quot;Bostonquot;/> <mx:Object label=quot;MTquot; data=quot;Helenaquot;/> <mx:Object label=quot;MEquot; data=quot;Augustaquot;/> <mx:Object label=quot;MSquot; data=quot;Jacksonquot;/> <mx:Object label=quot;MNquot; data=quot;Saint Paulquot;/> </mx:Array> </mx:ArrayCollection>
  • 47. Filtrare un‘ArrayCollection /* Function to filter out all items with labels that are not in the range of M-N. */ public function stateFilterFunc(item:Object):Boolean { return item.label >= quot;Mquot; && item.label < quot;Oquot;; } /* Function to apply the filter function the ICollectionView. */ public function filterAC():void { myAC.filterFunction=stateFilterFunc; /* Refresh the collection view to apply the filter. */ myAC.refresh(); } /* Function to Reset the view to its original state. */ public function resetAC():void { myAC.filterFunction=null; myAC.sort=null; myAC.refresh(); }
  • 48. Cursori Le Collections espongono un cursore tramite il metodo createCursor() public var myAC:ICollectionView = new ArrayCollection(myArray); public var myCursor:IViewCursor; … myCursor=myAC.createCursor(); Proprietà e metodi: moveNext() e movePrevious() per spostarsi tra i record while (! myCursor.afterLast) { myCursor.moveNext(); } findAny(), findFirst(), findLast() per cercare un item myCursor.findFirst({label:quot;MEquot;, data:quot;Augustaquot;});
  • 49. Aggiungere, eliminare o modificare items usando i cursori -1 <mx:Script> <![CDATA[ import mx.collections.*; public var myArray:Array = [quot;AZquot;, quot;MAquot;, quot;MZquot;, quot;MNquot;, quot;MOquot;, quot;MSquot;]; [Bindable] public var myAC:ArrayCollection; public function initData():void { myAC = new ArrayCollection(myArray); Cancello il primo elemento } public function changeCollection():void { var myCursor:IViewCursor=myAC.createCursor(); var removedItem:String=String(myCursor.remove()); Aggiungo ME come 2 elemento myCursor.moveNext(); myCursor.insert(quot;MEquot;); Uso la funzione seek con il myCursor.seek(CursorBookmark.LAST, 1); parametro myCursor.insert(quot;MTquot;); CursorBookmark.LAST e un offset=1 per andare aggiungere ‗MT‘ come ultimo elemento
  • 50. Aggiungere, eliminare o modificare items usando i cursori -2 …. // Change MZ to MI. La findFirst() successiva var sort:Sort = new Sort(); richiede che la collezione myAC.sort=sort; sia ordinata myAC.refresh(); if (myCursor.findFirst(quot;MZquot;) && !myCursor.findFirst(quot;MIquot;)) { myCursor.remove(); myCursor.insert(quot;MIquot;); } } La collezione non prevede un metodo Replace
  • 51. Hierarchical data objects •Menu •MenuBar •PopUpMenuButton •Tree Flex gestisce 2 tipologie di dati gerarchici: 1. XML sotto forma di stringhe o oggetti XML, XMLList, o XMLListCollection) 2. Oggetti in cui i nodi figli si trovano nel campo children [Bindable] public var fileSystemStructure:Object = {label:quot;mxquot;, children: [ {label:quot;Containersquot;, children: [ {label:quot;Accordianquot;, children:[]}, {label:quot;DividedBoxquot;, children: [ {label:quot;BoxDivider.asquot;, data:quot;BoxDivider.asquot;}, {label:quot;BoxUniter.asquot;, data:quot;BoxUniter.asquot;}]}, {label: quot;Gridquot;, children:[]}]}, {label: quot;Controlsquot;, children: [ {label: quot;Alertquot;, data: quot;Alert.asquot;}, {label: quot;Stylesquot;, children: [ {label: quot;AlertForm.asquot;, data:quot;AlertForm.asquot;}]}, {label: quot;Treequot;, data: quot;Tree.asquot;}, {label: quot;Buttonquot;, data: quot;Button.asquot;}]}, {label: quot;Corequot;, children:[]} ]};
  • 52. Data descriptors Sono classi che interfacciano i controlli gerarchici con i data provider. Flex espone 2 interfacce Data Descriptor: •ITreeDataDescriptor utilizzato dai controlli Tree •IMenuDataDescriptor utilizzato dai controlli Menu, MenuBar, e PopUpMenuButton La classe DefaultDataDescriptor implementa entrambe le interfacce.
  • 53. Data descriptors – proprietà e metodi Method Returns DefaultDataDescriptor behavior hasChildren(node, [model]) A Boolean value indicating For XML, returns true if the node has at least one child element. For other objects, returns true if the node has a nonempty children field. whether the node is a branch with children. A node‘s children. getChildren(node, For XML, returns an XMLListCollection with the child elements. For other Objects, returns the contents of the node‘s children field. [collection]) isBranch(node, [collection]) Whether a node is a branch. For XML, returns true if the node has at least one child, or if it has an isBranch attribute. For other Objects, returns true if the node has an isBranch field. getData(node, [collection]) The node data. Returns the node. addChildAt(node, child, A Boolean value indicating For all cases, inserts the node as a child object before the node currently in index, [model]) whether the operation succeeded. the index location. For all cases, removes the child of the node in the index location. removeChildAt(node, index, A Boolean value indicating [model]) whether the operation succeeded. getType(node) A String with the menu node type. For XML, returns the value of the type attribute of the node. For other Objects, returns the contents of the node‘s type field. (IMenuDataDescriptor only) Meaningful values are check, radio, and separator. isEnabled(node) A Boolean value indicating For XML, returns the value of the enabled attribute of the node. For other Objects, returns the contents of the node‘s enabled field. (IMenuDataDescriptor only) whether a menu node is enabled. setEnabled(node, value) For XML, sets the value of the enabled attribute of the node to true or false. For other Objects, sets the contents of the node‘s enabled field. (IMenuDataDescriptor only)
  • 54. Il tag <mx:Model> Consente la definizione di un data provider in MXML Presenta i seguenti vantaggi: • La struttura è più leggibile perchè in formato XML • Le strutture sono collegabili a variabili ActionScript e quindi si può usare <mx:Model> per creare un data provider che mostri dati dinamici
  • 55. Il tag <mx:Model> - Esempio - 1 <?xml version=quot;1.0quot;?> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot; xmlns=quot;*quot;> <mx:Script> <![CDATA[ import mx.controls.Menu; public var productMenu:Menu; public function initMenu(): void { productMenu = Menu.createMenu(null, Products.Department); productMenu.setStyle(quot;disabledColorquot;, 0xCC3366); productMenu.show(10,10); } ]]> </mx:Script>
  • 56. Il tag <mx:Model> - Esempio - 2 <mx:Model id=quot;Productsquot;> <Root> <Department label=quot;Toysquot;> <children label=quot;Teddy Bearsquot;/> <children label=quot;Action Figuresquot;/> <children label=quot;Building Blocksquot;/> </Department> <Department label=quot;Kitchenquot;> <children label=quot;Electronicsquot;> <children label=quot;Crock Potquot;/> <children label=quot;Panini Grillquot;/> </children> <children label=quot;Cookwarequot;> <children label=quot;Grill Panquot;/> <children label=quot;Iron Skilletquot; enabled=quot;falsequot;/> </children> </Department> <Department label=quot;{menuName.text}quot;> Item collegati ad <children label=quot;{item1.text}quot;/> oggetti della form <children label=quot;{item2.text}quot;/> <children label=quot;{item3.text}quot;/> </Department> </Root> </mx:Model>
  • 57. Il tag <mx:Model> - Esempio - 3 <mx:Button label=quot;Show Productsquot; click=quot;initMenu()quot;/> <mx:Form> <mx:FormItem label=quot;Third Submenu titlequot;> <mx:TextInput id=quot;menuNamequot; text=quot;Clothingquot;/> </mx:FormItem> <mx:FormItem label=quot;Item 1quot;> <mx:TextInput id=quot;item1quot; text=quot;Sweatersquot;/> </mx:FormItem> <mx:FormItem label=quot;Item 2quot;> <mx:TextInput id=quot;item2quot; text=quot;Shoesquot;/> </mx:FormItem> <mx:FormItem label=quot;Item 3quot;> <mx:TextInput id=quot;item3quot; text=quot;Jacketsquot;/> </mx:FormItem> </mx:Form> </mx:Application>
  • 58. Data objects basati su XML Utilizzare i tag <mx:XML> o <mx:XMLList> per definire gli oggetti XML/XMLList in MXML E‘ sempre possibile collegare i valori dei nodi ad oggetti dell‘applicazione; ad esempio: <mx:XMLList id=quot;myXMLListquot;> <child name=quot;{textInput1.text}quot;/> <child name=quot;{textInput2.text}quot;/> </mx:XMLList> Se i dati devono cambiare, occorre prima convertire gli oggetti XML o XMLList in un XMLListCollection ed effettuare le modifiche su di esso <mx:XML id=quot;capitalsquot;> <root> <Capitals label=quot;U.S. State Capitalsquot;> <capital label=quot;ALquot; value=quot;Montgomeryquot;/> <capital label=quot;AKquot; value=quot;Juneauquot;/> </Capitals> <Capitals label=quot;Canadian Province Capitalsquot;> <capital label=quot;ABquot; value=quot;Edmontonquot;/> <capital label=quot;BCquot; value=quot;Victoriaquot;/> </Capitals> </root> </mx:XML> <mx:XMLListCollection id=quot;capitalCollquot; source=quot;{capitals.Capitals}quot;/>
  • 59. XMLListCollection -1 Espone le funzionalità delle collection per la classe XMLList <?xml version=quot;1.0quot;?> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot;> <mx:Script> <![CDATA[ import mx.collections.XMLListCollection; import mx.collections.ArrayCollection; [Bindable] public var myData:XML= <catalog> <category name=quot;Meatquot;> <product name=quot;Buffaloquot;/> <product name=quot;T Bone Steakquot;/> </category> <category name=quot;Vegetablesquot;> <product name=quot;Broccoliquot;/> <product name=quot;Yellow Peppersquot;/> </category> <category name=quot;Fruitquot;> <product name=quot;Bananasquot;/> <product name=quot;Grapesquot;/> <product name=quot;Strawberriesquot;/> </category> </catalog>;
  • 60. XMLListCollection -2 [Bindable] public var listDP:XMLListCollection = new XMLListCollection(new XMLList()); private function doTreeSelect():void { if (prodTree.selectedItem) listDP.addItem(prodTree.selectedItem.copy()); } private function doListRemove():void { if (prodList.selectedItem) listDP.removeItemAt(prodList.selectedIndex); } ]]> </mx:Script> <mx:HBox> <mx:Tree id=quot;prodTreequot; dataProvider=quot;{myData}quot; width=quot;200quot; showRoot=quot;falsequot; labelField=quot;@namequot;/> <mx:VBox> <mx:Button id=quot;treeSelectquot; label=quot;Add to List― click=quot;doTreeSelect()quot;/> <mx:Button id=quot;listRemovequot; label=quot;Remove from List― click=quot;doListRemove()quot;/> </mx:VBox> <mx:List id=quot;prodListquot; dataProvider=quot;{listDP}quot; width=quot;200― labelField=quot;@namequot;/> </mx:HBox> </mx:Application>
  • 61. ArrayCollection da RemoteObject <?xml version=quot;1.0quot;?> <mx:Application xmlns:mx=quot;http://www.adobe.com/2006/mxmlquot; verticalGap=quot;10quot;> <mx:Script> <![CDATA[ import mx.controls.Alert; import mx.utils.ArrayUtil; ]]> </mx:Script> <mx:RemoteObject id=quot;employeeROquot; destination=quot;roDestquot; showBusyCursor=quot;truequot; fault=quot;Alert.show(event.fault.faultString, 'Error');quot;> <mx:method name=quot;getListquot;> <mx:arguments> <deptId>{dept.selectedItem.data}</deptId> </mx:arguments> </mx:method> </mx:RemoteObject> <mx:ArrayCollection id=quot;employeeAC‖ source=quot;{ArrayUtil.toArray(employeeRO.getList.lastResult)}quot;/> … <mx:DataGrid dataProvider=quot;{employeeAC}quot; width=quot;100%quot;> <mx:columns> <mx:DataGridColumn dataField=quot;namequot; headerText=quot;Namequot;/> <mx:DataGridColumn dataField=quot;phonequot; headerText=quot;Phonequot;/> <mx:DataGridColumn dataField=quot;emailquot; headerText=quot;Emailquot;/> </mx:columns> </mx:DataGrid>
  • 62. Datagrids, AdvancedDatagrids ItemRenderer e ItemEditor
  • 63. Differenze fra Datagrid e AdvancedDatagrid • Utilizzo delle GroupedCollection • Integrazione dell‘oggetto TreeView e utilizzo delle HierarchicalCollection • Multicolumn sorting <mx:XML source=quot;../assets/xml/sample.xmlquot; id=quot;xmlSourcequot; /> <mx:XMLListCollection id=quot;productsquot; source=quot;{xmlSource.Product}quot; /> <mx:AdvancedDataGrid editable=quot;truequot; x=quot;10quot; y=quot;10quot; id=quot;adg1quot; designViewDataType=quot;flatquot; width=quot;478quot; height=quot;289quot; dataProvider=quot;{products}quot;> <mx:columns> <mx:AdvancedDataGridColumn headerText=quot;IDquot; dataField=quot;IDquot; editable=quot;falsequot; /> <mx:AdvancedDataGridColumn headerText=quot;Namequot; dataField=quot;Namequot; editable=quot;falsequot; /> <mx:AdvancedDataGridColumn headerText=quot;Pricequot; dataField=quot;Pricequot;> </mx:column> </mx:AdvancedDataGrid>
  • 64. ItemRenderer • Per personalizzare la renderizzazione di una cella di una Datagrid o di una AdvancedDataGrid è necessario utilizzare la classe ItemRender • Per default, la cella viene visualizzata come Label senza formattazione • E‘ possibile creare un custom ItemRenderer estendendo la classe di riferimento <mx:AdvancedDataGridColumn headerText=quot;Pricequot; dataField=quot;Pricequot;> <mx:itemRenderer> <mx:Component> <components:TestRenderer></components:TestRenderer> </mx:Component> </mx:itemRenderer> </mx:AdvancedDataGridColumn> public class TestRenderer extends Label E sovrascrivendo il setter della proprietà data: nell‘esempio seguente la label apparirà rossa se il valore di Price sarà compreso fra 100 e 150 override public function set data(value:Object):void { super.data = value; if (Number(value.Price) >= 100 && Number(value.Price) <= 150) this.setStyle(quot;colorquot;, quot;redquot;); }
  • 65. ItemEditor • Datagrid e AdvancedDataGrids danno la possibilità di modificare il dataProvider direttamente dalle celle • Per default, l‘ItemEditor usato è un TextInput • E‘ possibile estendere l‘ItemEditor inserendo logica custom o creare un classe apposita • Le DataGridColumn e le AdvancedDatagridColumn sono editabili di default • L‘editorDataField può essere diverso dal dataField <mx:itemEditor> <mx:Component> <mx:VBox backgroundColor=quot;Yellowquot;> <mx:Script> <![CDATA[ [Bindable] public var cbSelected:Boolean; ]]> </mx:Script> <mx:CheckBox label=quot;Sell this product?quot; id=quot;cbIsSeleablequot; selected=quot;{data.Seleable}quot; click=quot;cbSelected=cbIsSeleable.selectedquot; /> </mx:VBox> </mx:Component> </mx:itemEditor>
  • 66. Remote Procedure Call: le classi HTTPService, WebService, RemoteObject
  • 67. Tipologie di connessione • REST style web service (es. Pagina PHP, JSP o servlet, o pagina ColdFusion) tramite HTTPService component • SOAP Web services tramite il WebService component • Adobe Action Message Format (AMF) remoting services tramite RemoteObject component; più veloce perchè non occorre formattazione XML dato che accede direttamente all‘oggetto Java o al componente ColdFusion o tramite WebORB per .NET)
  • 68. HTTPService •La classe HTTPService permette di inviare le richieste HTTP GET, POST, HEAD, OPTIONS, PUT, TRACE, and DELETE ed elaborare le risposte nell‘applicazione Flex. •I multpart form POSTs non sono supportati •In questo esempio viene richiamata una pagina PHP che richiede 2 parametri: <?xml version=quot;1.0quot; encoding=quot;utf-8quot;?> <mx:Application> ... <mx:HTTPService id=quot;userRequestquot; url=quot;http://server/myproj/request_post2.phpquot; useProxy=quot;falsequot; method=quot;POSTquot;> <mx:request xmlns=quot;quot;> <username>{username.text}</username> <emailaddress>{emailaddress.text}</emailaddress> </mx:request> </mx:HTTPService> </mx:Application>
  • 69. WebService • La classe WebService permette di effettuare richieste SOAP in POST verso l‘endpoint specificato dal WSDL del webservice stesso e gestire gli oggetti serializzati nella risposta • In questo esempio vengono richiamati due metodi del webservice definito dalla proprietà wsdl: <mx:Application> ... <mx:WebService id=quot;userRequest― wsdl=quot;http://server:8500/flexapp/returncfxml.cfc?wsdlquot;> <mx:operation name=quot;returnRecordsquot; resultFormat=quot;objectquot; fault=quot;mx.controls.Alert.show(event.fault.faultString)quot; result=quot;remotingCFCHandler(event)quot;/> <mx:operation name=quot;insertRecordquot; result=quot;insertCFCHandler()― fault=quot;mx.controls.Alert.show(event.fault.faultString)quot;/> </mx:WebService> </mx:Application>
  • 70. AMF (Action Message Format) • Il canale di comunicazione AMF permette di effettuare richieste asincrone verso un endpoint JAVA , ColdFusion, PHP, .NET e avere in risposta un oggetto interrogabile tramite le sue proprietà. • AMF è messo a dispozione da webapps come BlazeDS, DataServices di Adobe LiveCycle, WEBOrb .NET (anche per Rails e PHP) • Differenze fra BlazeDS e DataServices: • No PDF Generator • No RTMP (Real Time Messaging Protocol) • No offline datas
  • 71. RemoteObject – 1 • RemoteObject è la classe che si occupa delle richieste remote in AMF • La proprietà principale della classe RemoteObject è destination • La configurazione dei canali AMF e delle destination è specificata nel file services-config.xml • Il file services-config.xml deve essere incluso in compilazione del Flex dalla direttiva di compilazione –services -services quot;C:javawebservertomcatwebappssamplesWEB-INFflexservices- config.xml― Contenuto di services-config.xml <channel-definition id=quot;my-amfquot; class=quot;mx.messaging.channels.AMFChannelquot;> <endpoint url=quot;http://{server.name}:{server.port}/{context.root}/messagebroker/amfquot; class=quot;flex.messaging.endpoints.AMFEndpointquot;/> </channel-definition> <default-channels> <channel ref=quot;my-amfquot;/> </default-channels> <destination id=quot;productquot;> <properties> <source>flex.samples.product.ProductService</source></properties></destination>
  • 72. Chiamare i metodi remoti • Nel services-config la classe remota ProductService è associata alla destination product • Per invocare i metodi remoti di ProductService è necessario utilizzare la classe ActionScript RemoteObject instanziata con il parametro stringa che rappresenta il nome della destination da utilizzare (quindi della classe JAVA remota) var ro:RemoteObject = new RemoteObject(―product‖); L‘oggetto ―ro‖ ora rappresenta la classe JAVA remota ProductService esposta tramite BlazeDS • La classe remota ProductService espone il metodo getProductsByName ed ha come parametro il nome del prodotto da ricercare • ro.getProductsByName effettua una chiamata verso la classe remota • Lato JAVA il metodo getProductsByName restituisce una List di oggetti Product che viene serializzata in Flex in un oggetto ArrayCollection di Product
  • 73. Esempi di chiamate a metodi remoti - In MXML <mx:RemoteObject id=quot;srvquot; destination=quot;productquot;> <mx:method name=―getProductsByNamequot; result=―getResult(event)quot;/> </mx:RemoteObject> srv.getProductsByName(―nokia e51‖); private function getResult(event:ResultEvent):void { var products:ArrayCollection = event.result as ArrayCollection; } - In ActionScript var ro:RemoteObject = new RemoteObject(quot;productquot;); ro.addEventListener(ResultEvent.RESULT, getResult); ro.getProductsByName(―nokia e51‖); private function getResult(e:ResultEvent):void { var products:ArrayCollection = event.result as ArrayCollection; }
  • 74. Gestire gli eventi di Result e Fault • La classe RemoteObject effettua chiamate asincrone verso l‘endpoint JAVA • E‘ necessario gestire gli eventi di Result (dati ricevuti) e Fault (errore durante la richiesta) • E‘ possibile associate l‘event listener in modo generalizzato a tutte le chiamate del RemoteObject o ad ogni singolo metodo se è necessario gestire la risposta in modo particolare • Ogni metodo remoto rappresenta una classe ActionScript Operation ed implementa EventDispatcher var ro:RemoteObject = new RemoteObject(―product‖); ro.addEventListener(ResultEvent.RESULT, getResult); ro.addEventListener(FaultEvent.FAULT, onFault); Oppure specificando result e fault per ogni metodo: ro.getProductsByName.addEventListener(ResultEvent.RESULT, getResult); ro.getProductsByName.addEventListener(FaultEvent.FAULT, onFault); Private function getResult(e:ResultEvent):void { } Private function onFault(e:FaultEvent):void { }
  • 75. ResultEvent e FaultEvent • ResultEvent e FaultEvent estendono la classe generica Event • ResultEvent è usato per gestire l‘oggetto ricevuto dalla chiamata remota • FaultEvent è usato per gestire l‘errore durante la richiesta e visualizzare il messaggio di errore relativo • L‘oggetto ricevuto è contenuto nella proprietà result di ResultEvent ed è di tipo object (classe generica) e deve essere convertito alla classe di riferimento per l‘utilizzo in ActionScript • L‘errore è contenuto nella proprietà fault (tipo oggetto Fault) di FaultEvent private function getResult(e:ResultEvent):void { this.lastResult = e.result as ArrayCollection; } private function onFault(e:FaultEvent):void { Alert.show(e.fault.message); }
  • 76. Notificare la ricezione dei dati • Se si utilizza una classe ActionScript che gestisce le chiamate tramite RemoteObject è necessario notificare all‘applicazione o alle classi chiamanti l‘effettiva ricezione dei dati • Tale classe deve implementare EventDispatcher • Accedere ai dati associati a RemoteObject prima della effettiva ricezione risulta in una nullpointer execption • Nell‘event listener associato al ResultEvent è possibile effettuare un dispatch forzato di un evento custom che provveda al trattamento dei dati lato applicazione
  • 77. Metadata tag [RemoteClass] • Lato flex è necessario creare le classi ActionScript che rappresentano gli oggetti che vengono seralizzatideserializzati sul canale AMF • Nella classe ActionScript si specifica il metadata tag RemoteClass seguito dalla classe emota di riferimento RemoteClass(alias=quot;flex.samples.product.Productquot;)] public class Product { } e lato JAVA package flex.samples.product; public class Product implements Serializable { …. Le classi remote devono implementare le interfacce per la serializzazione come Serializable o ISerializable (java.io)
  • 78. Risorse • Reply : http://www.reply.it • Flex : http://www.flex.org • AIR : http://www.adobe.com/products/air/ • Flex ShowCase : http://flex.org/showcase/ • LiveDocs Flex 3: http://livedocs.adobe.com/flex/3/html/ • LiveDocs AS3 : http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/ • BlazeDS : http://opensource.adobe.com/wiki/display/blazeds/BlazeDS/ • LiveCycle : http://www.adobe.com/products/livecycle/ • WebORB : http://www.themidnightcoders.com/products.html • Flex Developers .it : http://flex.actionscript.it/index.php?title=Pagina_principale
  • 79. • Francesco Bramato @ Aktive Reply – f.bramato@reply.it

×