Mate Flex Framework
Using Flex Frameworks to Build Data-
Driven Applications




 Flex@Beach'10
What is Mate?




                             Event Handling



                  <MXML>
                           Depen...
Sample Projects

   InsyncMate1
        Exact copy of original app with a model and central event handling



   Insync...
Before & After
Contact List




 Flex@Beach'10
ContactList.mxml


      Toolbar.mxml




                     ContactList.mxml

  Flex@Beach'10
ContactList.mxml - Plain version

<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">

<mx:Script>
       [Bindable]	 	
...
ContactList.mxml - Plain version

<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">

<mx:Script>
       [Bindable]	 	
...
ContactList.mxml - Plain version

<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">

<mx:Script>
       [Bindable]	 	
...
ContactList.mxml - Plain version

<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">

<mx:Script>
       [Bindable]	 	
...
ContactList.mxml - Plain version

<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">

<mx:Script>
       [Bindable]	 	
...
ContactList.mxml - Plain version

<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">

<mx:Script>
       [Bindable]	 	
...
Plain version



                    calls search
                                       view
MainView


                 ...
Open file (InsyncMate1):


                  src

                        insync

                            mate

       ...
ContactList.mxml - Mate version 1

<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%">

	    ...
ContactList.mxml - Mate version 1

<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%">

	    ...
ContactList.mxml - Mate version 1

<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%">

	    ...
Open file (InsyncMate1):


                  src

                        insync

                            mate

       ...
Services.mxml - Mate version 1


<Object xmlns="*" xmlns:mx="http://www.adobe.com/2006/mxml">

	

     <mx:RemoteObject id...
Services.mxml - Mate version 1


<Object xmlns="*" xmlns:mx="http://www.adobe.com/2006/mxml">

	   <MockRemoteObject id="c...
Open file (InsyncMate1):


                  src

                        insync

                            mate

       ...
ContactsManager.as - Mate version 1

public class ContactsManager extends EventDispatcher {

             // property to s...
ContactsManager.as - Mate version 1

public class ContactsManager extends EventDispatcher {

             // property to s...
ContactsManager.as - Mate version 1

public class ContactsManager extends EventDispatcher {

             // property to s...
Open file (InsyncMate1):


                  src

                        insync

                            mate

       ...
Toolbar.mxml - Mate version 1


<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml...
Open file (InsyncMate1):


                  src

                        insync

                            mate

       ...
MainMap.mxml - Mate version 1

<EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/"
xmlns...
MainMap.mxml - Mate version 1

<EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/"
xmlns...
MainMap.mxml - Mate version 1

<EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/"
xmlns...
MainMap.mxml - Mate version 1

<EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/"
xmlns...
MainMap.mxml - Mate version 1

<EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/"
xmlns...
MainMap.mxml - Mate version 1

<EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/"
xmlns...
MainMap.mxml - Mate version 1

<EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/"
xmlns...
Open file (InsyncMate1):


                  src

                        InsyncMate1.mxml




  Flex@Beach'10             ...
InsyncMate1.mxml (version 1)


<?xml version="1.0" encoding="utf-8"?>
<mx:Application
	xmlns:mx="   http://www.adobe.com/2...
InsyncMate1.mxml (version 1)


<?xml version="1.0" encoding="utf-8"?>
<mx:Application
	xmlns:mx="   http://www.adobe.com/2...
InsyncMate1.mxml (version 1)


<?xml version="1.0" encoding="utf-8"?>
<mx:Application
	xmlns:mx="   http://www.adobe.com/2...
Debugging Output

<EventHandlers (started)    type="SearchEvent.SEARCH" (search)   priority="0"
useCapture="false"   useWe...
Debugging Output

<EventHandlers (started)    type="SearchEvent.SEARCH" (search)   priority="0"
useCapture="false"   useWe...
Debugging Output

<EventHandlers (started)    type="SearchEvent.SEARCH" (search)   priority="0"
useCapture="false"   useWe...
Event Handling

                                          Event Bus



                    Toolbar


                     ...
Open file (InsyncMate1):


                  src

                        insync

                            mate

       ...
MainMap.mxml - Mate version 1

<EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/">




...
Injection

                     Event Bus




       ContactList




  Flex@Beach'10
Injection

                         Event Bus

                     1   creationComplete
                         dispatch...
Injection

                         Event Bus

                     1   creationComplete
                         dispatch...
Injection

                         Event Bus

                     1   creationComplete
                         dispatch...
Injection

                         Event Bus

                     1   creationComplete
                         dispatch...
Injection

                                    Event Bus

                                1   creationComplete
           ...
Injection

                                Event Bus




       ContactList



                  3   binding
             ...
Version 1
Contact Form




 Flex@Beach'10
ContactEvent.SAVE   ContactEvent.DELETE




Flex@Beach'10
Open file (InsyncMate2):


                  src

                        insync

                            mate

       ...
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" label="{contact.id>0?contact.fullName:'New Contact'}">

	     <mx:Scr...
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" label="{contact.id>0?contact.fullName:'New Contact'}">

	      <mx:Sc...
Event Handling

                                          Event Bus



                    Toolbar


                     ...
<mx:Form>
	    	   <mx:FormItem label="Id">
	    	   	    <mx:TextInput text="{contact.id}" enabled="false"/>
	    	   </m...
<mx:Form>
	    	   <mx:FormItem label="Id">
	    	   	    <mx:TextInput text="{contact.id}" enabled="false"/>
	    	   </m...
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" label="{contact.id>0?contact.fullName:'New Contact'}">

	   <mx:Scrip...
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" label="{contact.id>0?contact.fullName:'New Contact'}">

	   <mx:Scrip...
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" label="{contact.id>0?contact.fullName:'New Contact'}">

	   <mx:Scrip...
Open file (InsyncMate1):


                  src

                        insync

                            mate

       ...
<EventMap>



	        <EventHandlers type="{ ContactEvent.SAVE }">
	        	
	        	   <RemoteObjectInvoker instance=...
<EventMap>




 	        <EventHandlers type="{ ContactEvent.SAVE }">
 	        	
 	        	   <RemoteObjectInvoker insta...
<EventMap>




	        <EventHandlers type="{ ContactEvent.SAVE }">
	        	
	        	   <RemoteObjectInvoker instance...
<EventMap>



  	        <EventHandlers type="{ ContactEvent.SAVE }">
  	        	
  	        	   <RemoteObjectInvoker ins...
<EventMap>




  	        <EventHandlers type="{ ContactEvent.SAVE }">
  	        	
  	        	   <RemoteObjectInvoker in...
<EventMap>




 	        <EventHandlers type="{ ContactEvent.SAVE }">
 	        	
 	        	   <RemoteObjectInvoker insta...
Open file (InsyncMate1):


                  src

                        insync

                            mate

       ...
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" label="{contact.id>0?contact.fullName:'New Contact'}">

	   <mx:Scrip...
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" label="{contact.id>0?contact.fullName:'New Contact'}">

	   <mx:Scrip...
Saving a contact

                     Event Bus




                                 Remote Object
                      ...
Version 3
Contact Form




 Flex@Beach'10
Presentation Model

                                     Event Bus




                    • User input & visualization
  ...
Presentation Model

                                     Event Bus




                    • User input & visualization
  ...
Presentation Model

                      Event Bus




                                  Remote Object
                  ...
Presentation Model

                                  Event Bus




                                              Remote O...
Presentation Model

                                  Event Bus




                                              Remote O...
Open file (InsyncMate3):


                  src

                        insync

                            mate

       ...
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">

	   <mx:Script>
	   	   	    [Bindable]
	   	   	    public var mod...
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">

	   <mx:Script>
	   	   	    [Bindable]
	   	   	    public var mod...
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">

	   <mx:Script>
	   	   	    [Bindable]
	   	   	    public var mod...
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">

	   <mx:Script>
	   	   	    [Bindable]
	   	   	    public var mod...
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">

	   <mx:Script>
	   	   	    [Bindable]
	   	   	    public var mod...
Open file (InsyncMate3):


                  src

                        insync

                            mate

       ...
public class ContactFormPresentationModel extends EventDispatcher {

	   	       // ----------------------------------
	  ...
public class ContactFormPresentationModel extends EventDispatcher {

	   	      // ----------------------------------
	   ...
-----------------------------------
	 private var dispatcher:IEventDispatcher;
	 public function ContactFormPresentationMo...
-----------------------------------
	 private var dispatcher:IEventDispatcher;
	 public function ContactFormPresentationMo...
-----------------------------------
	 private var dispatcher:IEventDispatcher;
	 public function ContactFormPresentationMo...
// Update functions ----------------------------------------------
	   	   public function updateFirstName( firstName:Stri...
Open file (InsyncMate3):


                  src

                        insync

                            mate

       ...
ContactsManager.as (InsyncMate3)

	   public class ContactsManager extends EventDispatcher
	   {
	   	   private var editO...
ContactsManager.as (InsyncMate3)

	   public class ContactsManager extends EventDispatcher
	   {
	   	   private var editO...
Open file (InsyncMate3):


                  src

                        insync

                            mate

       ...
ContactMap.mxml

<LocalEventMap xmlns:mx="http://www.adobe.com/2006/mxml"	xmlns="http://mate.asfusion.com/">
	
<!-- ~~~~~~...
ContactMap.mxml

<LocalEventMap xmlns:mx="http://www.adobe.com/2006/mxml"	xmlns="http://mate.asfusion.com/">
	
<!-- ~~~~~~...
ContactMap.mxml (InsyncMate3)

<!-- ContactEvent.SAVE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
	  ...
Version 3
Modules




 Flex@Beach'10
Open folder (InsyncMate3):


                  src

                        insync

                            mate

    ...
ContactModule.mxml
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml">
	
	   <mx:Script>
	   	      	      public functi...
ContactModule.mxml
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml">
	
	   <mx:Script>
	   	      	      public functi...
ContactModule.mxml
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml">
	
	   <mx:Script>
	   	      	      public functi...
Open file (InsyncMate3):


                  src

                        insync

                            mate

       ...
ContactMap.mxml

<LocalEventMap xmlns:mx="http://www.adobe.com/2006/mxml"	xmlns=" http://mate.asfusion.com/">
  	
<!-- Sea...
ContactMap.mxml

<LocalEventMap xmlns:mx="http://www.adobe.com/2006/mxml"	xmlns=" http://mate.asfusion.com/">
  	
<!-- Sea...
ContactMap.mxml

<LocalEventMap xmlns:mx="http://www.adobe.com/2006/mxml"	xmlns="http://mate.asfusion.com/">
  	
<!-- Sear...
ContactMap.mxml

<LocalEventMap xmlns:mx="http://www.adobe.com/2006/mxml"	xmlns="http://mate.asfusion.com/">
  	
<!-- Sear...
Learn more




                  http://mate.asfusion.com




  Flex@Beach'10               57
Upcoming SlideShare
Loading in …5
×

Mate

1,339 views

Published on

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

No Downloads
Views
Total views
1,339
On SlideShare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
38
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Mate

  1. 1. Mate Flex Framework Using Flex Frameworks to Build Data- Driven Applications Flex@Beach'10
  2. 2. What is Mate? Event Handling <MXML> Dependency Injection Flex@Beach'10
  3. 3. Sample Projects  InsyncMate1  Exact copy of original app with a model and central event handling  InsyncMate2  Logic moved to ContactManager  InsyncMate3  Better architecture with Presentation Model pattern  Modularized application  InsyncMate4  Modularized application Flex@Beach'10
  4. 4. Before & After Contact List Flex@Beach'10
  5. 5. ContactList.mxml Toolbar.mxml ContactList.mxml Flex@Beach'10
  6. 6. ContactList.mxml - Plain version <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> [Bindable] public var contacts:ArrayCollection; private var lastSearchStr:String; public function search(searchStr:String):void { service.getContactsByName(searchStr); lastSearchStr = searchStr; } private function getContacts_result(event:ResultEvent):void { contacts = event.result as ArrayCollection; } </mx:Script> <mx:RemoteObject id="service" destination="contacts" endpoint="http://localhost:8400/ messagebroker/amf"> <mx:method name="getContactsByName" result="getContacts_result(event)"/> </mx:RemoteObject> <mx:DataGrid id="dg" dataProvider="{ contacts }" doubleClick="dispatchEvent( new ContactEvent( ContactEvent.EDIT, dg.selectedItem as Contact) )" ... /> </mx:Canvas> Flex@Beach'10 6
  7. 7. ContactList.mxml - Plain version <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> [Bindable] public var contacts:ArrayCollection; private var lastSearchStr:String; public function search(searchStr:String):void { service.getContactsByName(searchStr); lastSearchStr = searchStr; } private function getContacts_result(event:ResultEvent):void { contacts = event.result as ArrayCollection; } </mx:Script> <mx:RemoteObject id="service" destination="contacts" endpoint="http://localhost:8400/ messagebroker/amf"> <mx:method name="getContactsByName" result="getContacts_result(event)"/> </mx:RemoteObject> <mx:DataGrid id="dg" dataProvider="{ contacts }" doubleClick="dispatchEvent( new ContactEvent( ContactEvent.EDIT, dg.selectedItem as Contact) )" ... /> </mx:Canvas> Flex@Beach'10
  8. 8. ContactList.mxml - Plain version <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> [Bindable] public var contacts:ArrayCollection; private var lastSearchStr:String; public function search(searchStr:String):void { called by parent service.getContactsByName(searchStr); executes service call lastSearchStr = searchStr; } private function getContacts_result(event:ResultEvent):void { contacts = event.result as ArrayCollection; } </mx:Script> <mx:RemoteObject id="service" destination="contacts" endpoint="http://localhost:8400/ messagebroker/amf"> <mx:method name="getContactsByName" result="getContacts_result(event)"/> </mx:RemoteObject> <mx:DataGrid id="dg" dataProvider="{ contacts }" doubleClick="dispatchEvent( new ContactEvent( ContactEvent.EDIT, dg.selectedItem as Contact) )" ... /> </mx:Canvas> Flex@Beach'10
  9. 9. ContactList.mxml - Plain version <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> [Bindable] public var contacts:ArrayCollection; private var lastSearchStr:String; public function search(searchStr:String):void { service.getContactsByName(searchStr); lastSearchStr = searchStr; } private function getContacts_result(event:ResultEvent):void { contacts = event.result as ArrayCollection; } </mx:Script> <mx:RemoteObject id="service" destination="contacts" endpoint="http://localhost:8400/ messagebroker/amf"> <mx:method name="getContactsByName" result="getContacts_result(event)"/> </mx:RemoteObject> <mx:DataGrid id="dg" dataProvider="{ contacts }" doubleClick="dispatchEvent( new ContactEvent( ContactEvent.EDIT, dg.selectedItem as Contact) )" ... /> </mx:Canvas> Flex@Beach'10
  10. 10. ContactList.mxml - Plain version <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> [Bindable] public var contacts:ArrayCollection; private var lastSearchStr:String; public function search(searchStr:String):void { service.getContactsByName(searchStr); lastSearchStr = searchStr; } private function getContacts_result(event:ResultEvent):void { contacts = event.result as ArrayCollection; } </mx:Script> <mx:RemoteObject id="service" destination="contacts" endpoint="http://localhost:8400/ messagebroker/amf"> <mx:method name="getContactsByName" result="getContacts_result(event)"/> </mx:RemoteObject> <mx:DataGrid id="dg" dataProvider="{ contacts }" doubleClick="dispatchEvent( new ContactEvent( ContactEvent.EDIT, dg.selectedItem as Contact) )" ... /> </mx:Canvas> Flex@Beach'10
  11. 11. ContactList.mxml - Plain version <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> [Bindable] public var contacts:ArrayCollection; private var lastSearchStr:String; public function search(searchStr:String):void { service.getContactsByName(searchStr); lastSearchStr = searchStr; } private function getContacts_result(event:ResultEvent):void { contacts = event.result as ArrayCollection; } </mx:Script> <mx:RemoteObject id="service" destination="contacts" endpoint="http://localhost:8400/ messagebroker/amf"> <mx:method name="getContactsByName" result="getContacts_result(event)"/> </mx:RemoteObject> <mx:DataGrid id="dg" dataProvider="{ contacts }" doubleClick="dispatchEvent( new ContactEvent( ContactEvent.EDIT, dg.selectedItem as Contact) )" ... /> </mx:Canvas> Flex@Beach'10
  12. 12. Plain version calls search view MainView services Toolbar business logic ContactList Flex@Beach'10
  13. 13. Open file (InsyncMate1): src insync mate ui views ContactList.mxml Flex@Beach'10 8
  14. 14. ContactList.mxml - Mate version 1 <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%"> <mx:Metadata> [Event(name="editContact", type="insync.mate.events.ContactEvent")] </mx:Metadata> <mx:Script> import mx.collections.ArrayCollection; import insync.mate.model.Contact; import insync.mate.events.ContactEvent; [Bindable] public var contacts:ArrayCollection; </mx:Script> <mx:DataGrid id="dg" dataProvider="{ contacts }" top=" 0" left="0" right=" 0" bottom="0" doubleClickEnabled=" true" doubleClick="dispatchEvent( new ContactEvent( ContactEvent.EDIT, dg.selectedItem as Contact) )"> Flex@Beach'10 <mx:columns> 9
  15. 15. ContactList.mxml - Mate version 1 <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%"> <mx:Metadata> [Event(name="editContact", type="insync.mate.events.ContactEvent")] </mx:Metadata> <mx:Script> import mx.collections.ArrayCollection; import insync.mate.model.Contact; import insync.mate.events.ContactEvent; [Bindable] public var contacts:ArrayCollection; provided by injection </mx:Script> <mx:DataGrid id="dg" dataProvider="{ contacts }" top=" 0" left="0" right=" 0" bottom="0" doubleClickEnabled=" true" doubleClick="dispatchEvent( new ContactEvent( ContactEvent.EDIT, dg.selectedItem as Contact) )"> Flex@Beach'10 <mx:columns> 9
  16. 16. ContactList.mxml - Mate version 1 <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%"> <mx:Metadata> [Event(name="editContact", type="insync.mate.events.ContactEvent")] </mx:Metadata> <mx:Script> import mx.collections.ArrayCollection; import insync.mate.model.Contact; import insync.mate.events.ContactEvent; no business logic [Bindable] not dependent on service public var contacts:ArrayCollection; </mx:Script> independent from Mate <mx:DataGrid id="dg" dataProvider="{ contacts }" top=" 0" left="0" right=" 0" bottom="0" doubleClickEnabled=" true" doubleClick="dispatchEvent( new ContactEvent( ContactEvent.EDIT, dg.selectedItem as Contact) )"> Flex@Beach'10 <mx:columns> 9
  17. 17. Open file (InsyncMate1): src insync mate services Services.mxml Flex@Beach'10 10
  18. 18. Services.mxml - Mate version 1 <Object xmlns="*" xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:RemoteObject id="contacts" destination="contacts" endpoint="http://localhost:8400/messagebroker/amf" /> </Object> centralized services Flex@Beach'10 11
  19. 19. Services.mxml - Mate version 1 <Object xmlns="*" xmlns:mx="http://www.adobe.com/2006/mxml"> <MockRemoteObject id="contacts" mockGenerator="{ MockContactService }" delay="3"> <methods> <MockMethod name="search" dataUrl="assets/xml/contacts.xml"/> </methods> </MockRemoteObject> </Object> Flex@Beach'10 11
  20. 20. Open file (InsyncMate1): src insync mate managers ContactsManager.as Flex@Beach'10 12
  21. 21. ContactsManager.as - Mate version 1 public class ContactsManager extends EventDispatcher { // property to store the last search keyword public var lastSearch:String = ""; // Read-only public variable used to access the current contacts to show in list private var _contacts:ArrayCollection; [Bindable(event="contactsChanged")] public function get contacts():ArrayCollection { return _contacts; } // Stores given contacts and the current search keyword public function saveContacts( list:ArrayCollection, searchKey:String ):void { _contacts = list; //trigger binding by dispatching change event dispatchEvent( new Event( "contactsChanged" ) ); lastSearch = searchKey; } } Flex@Beach'10 13
  22. 22. ContactsManager.as - Mate version 1 public class ContactsManager extends EventDispatcher { // property to store the last search keyword public var lastSearch:String = ""; // Read-only public variable used to access the current contacts to show in list private var _contacts:ArrayCollection; [Bindable(event="contactsChanged")] public function get contacts():ArrayCollection { return _contacts; } // Stores given contacts and the current search keyword public function saveContacts( list:ArrayCollection, searchKey:String ):void { _contacts = list; //trigger binding by dispatching change event dispatchEvent( new Event( "contactsChanged" ) ); lastSearch = searchKey; } } Flex@Beach'10 13
  23. 23. ContactsManager.as - Mate version 1 public class ContactsManager extends EventDispatcher { // property to store the last search keyword public var lastSearch:String = ""; // Read-only public variable used to access the current contacts to show in list private var _contacts:ArrayCollection; [Bindable(event="contactsChanged")] public function get contacts():ArrayCollection { return _contacts; } // Stores given contacts and the current search keyword public function saveContacts( list:ArrayCollection, searchKey:String ):void { _contacts = list; independent from services //trigger binding by dispatching change event dispatchEvent( new Event( "contactsChanged" ) ); easy to mock and test lastSearch = searchKey; } } Flex@Beach'10 13
  24. 24. Open file (InsyncMate1): src insync mate ui views Toolbar.mxml Flex@Beach'10 14
  25. 25. Toolbar.mxml - Mate version 1 <?xml version="1.0" encoding="utf-8"?> <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100%"> <mx:Metadata> [Event(name="search", type="insync.plain.events.SearchEvent")] [Event(name="addContact", type="insync.plain.events.ContactEvent")] </mx:Metadata> <mx:Script> <![CDATA[ import insync.plain.events.SearchEvent; import insync.plain.events.ContactEvent; ]]> </mx:Script> <mx:Button toolTip="Add Contact" click="dispatchEvent( new ContactEvent(ContactEvent.ADD))"/> <mx:Label text="Search:" /> <mx:TextInput id="searchBox" change="dispatchEvent( new SearchEvent(SearchEvent.SEARCH, searchBox.text))"/> </mx:Canvas> Flex@Beach'10 15
  26. 26. Open file (InsyncMate1): src insync mate maps MainMap.mxml Flex@Beach'10 16
  27. 27. MainMap.mxml - Mate version 1 <EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/" xmlns:services="insync.mate.services.*"> <services:Services id="services" /> <EventHandlers type="{ SearchEvent.SEARCH }"> <RemoteObjectInvoker instance="{ services.contacts }" method=" getContactsByName" arguments=" { event.searchStr }"> <resultHandlers> <MethodInvoker generator="{ ContactsManager }" method=" saveContacts" arguments=" { [resultObject, event.searchStr] }"/> </resultHandlers> </RemoteObjectInvoker> </EventHandlers> </EventMap> Flex@Beach'10 17
  28. 28. MainMap.mxml - Mate version 1 <EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/" xmlns:services="insync.mate.services.*"> <services:Services id="services" /> <EventHandlers type="{ SearchEvent.SEARCH }"> <RemoteObjectInvoker instance="{ services.contacts }" method=" getContactsByName" arguments=" { event.searchStr }"> <resultHandlers> <MethodInvoker generator="{ ContactsManager }" method=" saveContacts" arguments=" { [resultObject, event.searchStr] }"/> </resultHandlers> </RemoteObjectInvoker> </EventHandlers> </EventMap> Flex@Beach'10 17
  29. 29. MainMap.mxml - Mate version 1 <EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/" xmlns:services="insync.mate.services.*"> <services:Services id="services" /> <EventHandlers type="{ SearchEvent.SEARCH }"> <RemoteObjectInvoker instance="{ services.contacts }" method=" getContactsByName" arguments=" { event.searchStr }"> <resultHandlers> <MethodInvoker generator="{ ContactsManager }" method=" saveContacts" arguments=" { [resultObject, event.searchStr] }"/> </resultHandlers> </RemoteObjectInvoker> </EventHandlers> </EventMap> Flex@Beach'10 17
  30. 30. MainMap.mxml - Mate version 1 <EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/" xmlns:services="insync.mate.services.*"> <services:Services id="services" /> <EventHandlers type="{ SearchEvent.SEARCH }"> <RemoteObjectInvoker instance="{ services.contacts }" method=" getContactsByName" arguments=" { event.searchStr }"> <resultHandlers> <MethodInvoker generator="{ ContactsManager }" method=" saveContacts" arguments=" { [resultObject, event.searchStr] }"/> </resultHandlers> </RemoteObjectInvoker> </EventHandlers> </EventMap> Flex@Beach'10 17
  31. 31. MainMap.mxml - Mate version 1 <EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/" xmlns:services="insync.mate.services.*"> <services:Services id="services" /> <EventHandlers type="{ SearchEvent.SEARCH }"> <RemoteObjectInvoker instance="{ services.contacts }" method=" getContactsByName" arguments=" { event.searchStr }"> <resultHandlers> <MethodInvoker generator="{ ContactsManager }" method=" saveContacts" arguments=" { [resultObject, event.searchStr] }"/> </resultHandlers> </RemoteObjectInvoker> </EventHandlers> </EventMap> Flex@Beach'10 17
  32. 32. MainMap.mxml - Mate version 1 <EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/" xmlns:services="insync.mate.services.*"> <services:Services id="services" /> <EventHandlers type="{ SearchEvent.SEARCH }"> <RemoteObjectInvoker instance="{ services.contacts }" method=" getContactsByName" arguments=" { event.searchStr }"> <resultHandlers> <MethodInvoker generator="{ ContactsManager }" method=" saveContacts" arguments=" { [resultObject, event.searchStr] }"/> </resultHandlers> </RemoteObjectInvoker> </EventHandlers> </EventMap> Flex@Beach'10 17
  33. 33. MainMap.mxml - Mate version 1 <EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/" xmlns:services="insync.mate.services.*"> <services:Services id="services" /> <EventHandlers type="{ SearchEvent.SEARCH }"> <RemoteObjectInvoker instance="{ services.contacts }" method=" getContactsByName" service methods separated arguments=" { event.searchStr }"> from view and business <resultHandlers> logic <MethodInvoker generator="{ ContactsManager }" method=" saveContacts" arguments=" { [resultObject, event.searchStr] }"/> </resultHandlers> </RemoteObjectInvoker> </EventHandlers> </EventMap> Flex@Beach'10 17
  34. 34. Open file (InsyncMate1): src InsyncMate1.mxml Flex@Beach'10 18
  35. 35. InsyncMate1.mxml (version 1) <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" xmlns:views=" insync.mate.ui.views.*" xmlns:maps=" insync.mate.maps.*" xmlns:mate="http://mate.asfusion.com/"> <!-- Styles ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <mx:Style source="assets/styles/styles.css" /> <!-- EventMaps ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <maps:MainMap /> <!-- UI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <views:MainView/> <!-- Debugger ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <mate:Debugger level="{Debugger.ALL}" /> </mx:Application> Flex@Beach'10 19
  36. 36. InsyncMate1.mxml (version 1) <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" xmlns:views=" insync.mate.ui.views.*" xmlns:maps=" insync.mate.maps.*" xmlns:mate="http://mate.asfusion.com/"> <!-- Styles ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <mx:Style source="assets/styles/styles.css" /> <!-- EventMaps ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <maps:MainMap /> <!-- UI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <views:MainView/> <!-- Debugger ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <mate:Debugger level="{Debugger.ALL}" /> </mx:Application> Flex@Beach'10 19
  37. 37. InsyncMate1.mxml (version 1) <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" xmlns:views=" insync.mate.ui.views.*" xmlns:maps=" insync.mate.maps.*" xmlns:mate="http://mate.asfusion.com/"> <!-- Styles ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <mx:Style source="assets/styles/styles.css" /> <!-- EventMaps ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <maps:MainMap /> <!-- UI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <views:MainView/> <!-- Debugger ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <mate:Debugger level="{Debugger.ALL}" /> </mx:Application> Flex@Beach'10 19
  38. 38. Debugging Output <EventHandlers (started) type="SearchEvent.SEARCH" (search) priority="0" useCapture="false" useWeakReference="true" dispatcherType="inherit" scope="[object Scope]"> <RemoteObjectInvoker instance="[RemoteObject destination="contacts" channelSet="[ChannelSet null ]"]" arguments="Pam" showBusyCursor="false" makeObjectsBindable="true" method="getContactsByName" requestTimeout="0" debug="false"/> </EventHandlers (end) type="SearchEvent.SEARCH" (search)> Flex@Beach'10
  39. 39. Debugging Output <EventHandlers (started) type="SearchEvent.SEARCH" (search) priority="0" useCapture="false" useWeakReference="true" dispatcherType="inherit" scope="[object Scope]"> <RemoteObjectInvoker instance="[RemoteObject destination="contacts" channelSet="[ChannelSet null ]"]" arguments="Pam" showBusyCursor="false" makeObjectsBindable="true" method="getContactsByName" requestTimeout="0" debug="false"/> </EventHandlers (end) type="SearchEvent.SEARCH" (search)> <RemoteObjectInvoker instance="{ services.contacts }" method=" getContactsByName" debug="true" arguments=" { event.searchStr }"> Flex@Beach'10
  40. 40. Debugging Output <EventHandlers (started) type="SearchEvent.SEARCH" (search) priority="0" useCapture="false" useWeakReference="true" dispatcherType="inherit" scope="[object Scope]"> <RemoteObjectInvoker instance="[RemoteObject destination="contacts" channelSet="[ChannelSet null ]"]" arguments="Pam" showBusyCursor="false" makeObjectsBindable="true" method="getContactsByName" requestTimeout="0" debug="false"/> </EventHandlers (end) type="SearchEvent.SEARCH" (search)> <RemoteObjectInvoker instance="{ services.contacts }" method=" getContactsByName" debug="true" arguments=" { event.searchStr }"> <ServiceHandlers (started) type="SearchEvent.SEARCH" (search) token="[object AsyncToken]" priority="0" useCapture="false" useWeakReference="true" scope="[object ServiceScope]" dispatcherType="local"> <MethodInvoker method="saveContacts" arguments="[ [object Contact], Pam ]" generator="[class ContactsManager]" cache="inherit" registerTarget="true"/> </ServiceHandlers (end) type="SearchEvent.SEARCH" (search)> Flex@Beach'10
  41. 41. Event Handling Event Bus Toolbar Remote Object (Services.mxml) Model (ContactManager.as) View EventMap (ContactList.mxml) binding via Injection Flex@Beach'10
  42. 42. Open file (InsyncMate1): src insync mate maps MainMap.mxml Flex@Beach'10 22
  43. 43. MainMap.mxml - Mate version 1 <EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/"> <Injectors target="{ ContactList }"> <PropertyInjector targetKey="contacts" Takes advantage of source=" { ContactsManager }" sourceKey="contacts"/> bindings </Injectors> </EventMap> Flex@Beach'10 23
  44. 44. Injection Event Bus ContactList Flex@Beach'10
  45. 45. Injection Event Bus 1 creationComplete dispatched ContactList Flex@Beach'10
  46. 46. Injection Event Bus 1 creationComplete dispatched ContactList EventMap Flex@Beach'10
  47. 47. Injection Event Bus 1 creationComplete dispatched ContactList EventMap ContactManager Flex@Beach'10
  48. 48. Injection Event Bus 1 creationComplete dispatched ContactList 2 creates binding between model and view EventMap ContactManager Flex@Beach'10
  49. 49. Injection Event Bus 1 creationComplete dispatched ContactList 2 creates binding 3 binding between model updates and view EventMap ContactManager Flex@Beach'10
  50. 50. Injection Event Bus ContactList 3 binding updates ContactManager Flex@Beach'10
  51. 51. Version 1 Contact Form Flex@Beach'10
  52. 52. ContactEvent.SAVE ContactEvent.DELETE Flex@Beach'10
  53. 53. Open file (InsyncMate2): src insync mate ui views ContactForm.mxml Flex@Beach'10 27
  54. 54. <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" label="{contact.id>0?contact.fullName:'New Contact'}"> <mx:Script> <![CDATA[ [Bindable] public var contact:Contact; private function save():void { contact.firstName = firstName.text; contact.lastName = lastName.text; contact.email = email.text; contact.phone = phone.text; contact.address = address.text; contact.city = city.text; contact.state = state.text; contact.zip = zip.text; contact.pic = picture.source; dispatchEvent( new ContactEvent( ContactEvent.SAVE, contact ) ); } private function remove():void { dispatchEvent( new ContactEvent( ContactEvent.DELETE, contact ) ); } public function save_result( ):void { status.text = "Contact saved successfully"; } ]]> </mx:Script> Flex@Beach'10 ®
  55. 55. <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" label="{contact.id>0?contact.fullName:'New Contact'}"> <mx:Script> <![CDATA[ [Bindable] public var contact:Contact; private function save():void { contact.firstName = firstName.text; contact.lastName = lastName.text; contact.email = email.text; contact.phone = phone.text; contact.address = address.text; contact.city = city.text; contact.state = state.text; contact.zip = zip.text; contact.pic = picture.source; dispatchEvent( new ContactEvent( ContactEvent.SAVE, contact ) ); } private function remove():void { dispatchEvent( new ContactEvent( ContactEvent.DELETE, contact ) ); } public function save_result( ):void { status.text = "Contact saved successfully"; } ]]> </mx:Script> Flex@Beach'10
  56. 56. Event Handling Event Bus Toolbar Remote Object (Services.mxml) Model (ContactManager.as) View EventMap (ContactList.mxml) binding via Injection Flex@Beach'10
  57. 57. <mx:Form> <mx:FormItem label="Id"> <mx:TextInput text="{contact.id}" enabled="false"/> </mx:FormItem> <mx:FormItem label="First Name"> <mx:TextInput id="firstName" text="{contact.firstName}"/> </mx:FormItem> <mx:FormItem label="Last Name"> <mx:TextInput id="lastName" text="{contact.lastName}"/> </mx:FormItem> <mx:FormItem label="Email"> <mx:TextInput id="email" text="{contact.email}"/> </mx:FormItem> <-- all of the other fields here --> </mx:Form> <controls:PictureInput id="picture" source="{contact.pic}"/> <mx:Button label="Save" click="save()"/> <mx:Button label="Delete" click="remove()"/> <mx:Label id="status" /> </mx:Canvas> Flex@Beach'10
  58. 58. <mx:Form> <mx:FormItem label="Id"> <mx:TextInput text="{contact.id}" enabled="false"/> </mx:FormItem> <mx:FormItem label="First Name"> <mx:TextInput id="firstName" text="{contact.firstName}"/> </mx:FormItem> <mx:FormItem label="Last Name"> <mx:TextInput id="lastName" text="{contact.lastName}"/> </mx:FormItem> <mx:FormItem label="Email"> <mx:TextInput id="email" text="{contact.email}"/> </mx:FormItem> <-- all of the other fields here --> </mx:Form> <controls:PictureInput id="picture" source="{contact.pic}"/> <mx:Button label="Save" click="save()"/> <mx:Button label="Delete" click="remove()"/> <mx:Label id="status" /> </mx:Canvas> Flex@Beach'10
  59. 59. <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" label="{contact.id>0?contact.fullName:'New Contact'}"> <mx:Script> <![CDATA[ [Bindable] public var contact:Contact; private function save():void { contact.firstName = firstName.text; contact.lastName = lastName.text; contact.email = email.text; contact.phone = phone.text; contact.address = address.text; contact.city = city.text; contact.state = state.text; contact.zip = zip.text; contact.pic = picture.source; dispatchEvent( new ContactEvent( ContactEvent.SAVE, contact ) ); } private function remove():void { dispatchEvent( new ContactEvent( ContactEvent.DELETE, contact ) ); } public function save_result( ):void { status.text = "Contact saved successfully"; } ]]> </mx:Script> Flex@Beach'10 ®
  60. 60. <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" label="{contact.id>0?contact.fullName:'New Contact'}"> <mx:Script> <![CDATA[ [Bindable] public var contact:Contact; private function save():void { contact.firstName = firstName.text; contact.lastName = lastName.text; contact.email = email.text; contact.phone = phone.text; contact.address = address.text; contact.city = city.text; contact.state = state.text; contact.zip = zip.text; contact.pic = picture.source; dispatchEvent( new ContactEvent( ContactEvent.SAVE, contact ) ); } private function remove():void { dispatchEvent( new ContactEvent( ContactEvent.DELETE, contact ) ); } public function save_result( ):void { status.text = "Contact saved successfully"; } ]]> </mx:Script> Flex@Beach'10 ®
  61. 61. <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" label="{contact.id>0?contact.fullName:'New Contact'}"> <mx:Script> <![CDATA[ [Bindable] public var contact:Contact; private function save():void { contact.firstName = firstName.text; contact.lastName = lastName.text; contact.email = email.text; contact.phone = phone.text; contact.address = address.text; contact.city = city.text; contact.state = state.text; contact.zip = zip.text; contact.pic = picture.source; dispatchEvent( new ContactEvent( ContactEvent.SAVE, contact ) ); } private function remove():void { dispatchEvent( new ContactEvent( ContactEvent.DELETE, contact ) ); } public function save_result( ):void { status.text = "Contact saved successfully"; } ]]> </mx:Script> Flex@Beach'10
  62. 62. Open file (InsyncMate1): src insync mate maps MainMap.mxml Flex@Beach'10
  63. 63. <EventMap> <EventHandlers type="{ ContactEvent.SAVE }"> <RemoteObjectInvoker instance="{ services.contacts }" method=" save" arguments=" { event.contact }"> <resultHandlers> <CallBack method="save_result"/> <EventAnnouncer generator="{ SearchEvent }" type=" { SearchEvent.SEARCH }"> <Property targetKey="searchStr" source="{ ContactsManager }" sourceKey="lastSearch"/> </EventAnnouncer> </resultHandlers> </RemoteObjectInvoker> </EventHandlers> </EventMap> Flex@Beach'10
  64. 64. <EventMap> <EventHandlers type="{ ContactEvent.SAVE }"> <RemoteObjectInvoker instance="{ services.contacts }" method=" save" arguments=" { event.contact }"> <resultHandlers> <CallBack method="save_result"/> <EventAnnouncer generator="{ SearchEvent }" type=" { SearchEvent.SEARCH }"> <Property targetKey="searchStr" source="{ ContactsManager }" sourceKey="lastSearch"/> </EventAnnouncer> </resultHandlers> </RemoteObjectInvoker> </EventHandlers> </EventMap> ® Flex@Beach'10
  65. 65. <EventMap> <EventHandlers type="{ ContactEvent.SAVE }"> <RemoteObjectInvoker instance="{ services.contacts }" method=" save" arguments=" { event.contact }"> <resultHandlers> <CallBack method="save_result"/> <EventAnnouncer generator="{ SearchEvent }" type=" { SearchEvent.SEARCH }"> <Property targetKey="searchStr" source="{ ContactsManager }" sourceKey="lastSearch"/> </EventAnnouncer> </resultHandlers> </RemoteObjectInvoker> </EventHandlers> </EventMap> Flex@Beach'10
  66. 66. <EventMap> <EventHandlers type="{ ContactEvent.SAVE }"> <RemoteObjectInvoker instance="{ services.contacts }" method=" save" arguments=" { event.contact }"> <resultHandlers> <CallBack method="save_result"/> <EventAnnouncer generator="{ SearchEvent }" type=" { SearchEvent.SEARCH }"> <Property targetKey="searchStr" source="{ ContactsManager }" sourceKey="lastSearch"/> </EventAnnouncer> </resultHandlers> </RemoteObjectInvoker> </EventHandlers> </EventMap> ® Flex@Beach'10
  67. 67. <EventMap> <EventHandlers type="{ ContactEvent.SAVE }"> <RemoteObjectInvoker instance="{ services.contacts }" method=" save" arguments=" { event.contact }"> <resultHandlers> <CallBack method="save_result"/> <EventAnnouncer generator="{ SearchEvent }" type=" { SearchEvent.SEARCH }"> <Property targetKey="searchStr" source="{ ContactsManager }" sourceKey="lastSearch"/> </EventAnnouncer> </resultHandlers> </RemoteObjectInvoker> </EventHandlers> </EventMap> ® Flex@Beach'10
  68. 68. <EventMap> <EventHandlers type="{ ContactEvent.SAVE }"> <RemoteObjectInvoker instance="{ services.contacts }" method=" save" arguments=" { event.contact }"> <resultHandlers> <CallBack method="save_result"/> <EventAnnouncer generator="{ SearchEvent }" type=" { SearchEvent.SEARCH }"> <Property targetKey="searchStr" source="{ ContactsManager }" sourceKey="lastSearch"/> </EventAnnouncer> </resultHandlers> </RemoteObjectInvoker> </EventHandlers> </EventMap> ® Flex@Beach'10
  69. 69. Open file (InsyncMate1): src insync mate ui views ContactForm.mxml Flex@Beach'10
  70. 70. <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" label="{contact.id>0?contact.fullName:'New Contact'}"> <mx:Script> <![CDATA[ [Bindable] public var contact:Contact; private function save():void { contact.firstName = firstName.text; contact.lastName = lastName.text; contact.email = email.text; contact.phone = phone.text; contact.address = address.text; contact.city = city.text; contact.state = state.text; contact.zip = zip.text; contact.pic = picture.source; dispatchEvent( new ContactEvent( ContactEvent.SAVE, contact ) ); } private function remove():void { dispatchEvent( new ContactEvent( ContactEvent.DELETE, contact ) ); } public function save_result( ):void { status.text = "Contact saved successfully"; } ]]> </mx:Script> Flex@Beach'10
  71. 71. <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" label="{contact.id>0?contact.fullName:'New Contact'}"> <mx:Script> <![CDATA[ [Bindable] public var contact:Contact; private function save():void { contact.firstName = firstName.text; contact.lastName = lastName.text; contact.email = email.text; contact.phone = phone.text; contact.address = address.text; contact.city = city.text; contact.state = state.text; contact.zip = zip.text; contact.pic = picture.source; dispatchEvent( new ContactEvent( ContactEvent.SAVE, contact ) ); } private function remove():void { dispatchEvent( new ContactEvent( ContactEvent.DELETE, contact ) ); } public function save_result( ):void { status.text = "Contact saved successfully"; } ]]> </mx:Script> Flex@Beach'10
  72. 72. Saving a contact Event Bus Remote Object (Services.mxml) View (ContacForm.mxml) EventMap Flex@Beach'10
  73. 73. Version 3 Contact Form Flex@Beach'10
  74. 74. Presentation Model Event Bus • User input & visualization • Maintains its state • Dispatches events Remote Object • Receives data (Services.mxml) • Validates user input View (ContacForm.mxml) EventMap Flex@Beach'10
  75. 75. Presentation Model Event Bus • User input & visualization • Maintains its state • Dispatches events Remote Object • Receives data (Services.mxml) • Validates user input View (ContacForm.mxml) EventMap Flex@Beach'10
  76. 76. Presentation Model Event Bus Remote Object (Services.mxml) View (ContacForm.mxml) EventMap Flex@Beach'10
  77. 77. Presentation Model Event Bus Remote Object (Services.mxml) View Presentation (ContacForm.mxml) Model EventMap Flex@Beach'10
  78. 78. Presentation Model Event Bus Remote Object (Services.mxml) View Presentation (ContacForm.mxml) Model EventMap Flex@Beach'10
  79. 79. Open file (InsyncMate3): src insync mate contacts ui views ContactForm.mxml Flex@Beach'10
  80. 80. <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> [Bindable] public var model:ContactFormPresentationModel; </mx:Script> <mx:Form> <mx:FormItem label="Id"> <mx:TextInput text="{ model.contact.id }" enabled="false" /> </mx:FormItem> <mx:FormItem label="First Name"> <mx:TextInput id="firstName" text="{ model.contact.firstName }" change="model.updateFirstName( firstName.text )" /> </mx:FormItem> <-- all of the other fields here --> </mx:Form> <controls:PictureInput id="picture" source=" { model.contact.pic }"/> <mx:Button bottom="26" left="12" label="Save" click="model.save()"/> <mx:Button bottom="26" left="72" label="Delete" click="model.remove()"/> <mx:Label id="status" text="{ model.status }" /> </mx:Canvas> Flex@Beach'10 ®
  81. 81. <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> [Bindable] public var model:ContactFormPresentationModel; </mx:Script> <mx:Form> <mx:FormItem label="Id"> <mx:TextInput text="{ model.contact.id }" enabled="false" /> </mx:FormItem> <mx:FormItem label="First Name"> <mx:TextInput id="firstName" text="{ model.contact.firstName }" change="model.updateFirstName( firstName.text )" /> </mx:FormItem> <-- all of the other fields here --> </mx:Form> <controls:PictureInput id="picture" source=" { model.contact.pic }"/> <mx:Button bottom="26" left="12" label="Save" click="model.save()"/> <mx:Button bottom="26" left="72" label="Delete" click="model.remove()"/> <mx:Label id="status" text="{ model.status }" /> </mx:Canvas> ® Flex@Beach'10
  82. 82. <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> [Bindable] public var model:ContactFormPresentationModel; </mx:Script> <mx:Form> <mx:FormItem label="Id"> <mx:TextInput text="{ model.contact.id }" enabled="false" /> </mx:FormItem> <mx:FormItem label="First Name"> <mx:TextInput id="firstName" text="{ model.contact.firstName }" change="model.updateFirstName( firstName.text )" /> </mx:FormItem> <-- all of the other fields here --> </mx:Form> <controls:PictureInput id="picture" source=" { model.contact.pic }"/> <mx:Button bottom="26" left="12" label="Save" click="model.save()"/> <mx:Button bottom="26" left="72" label="Delete" click="model.remove()"/> <mx:Label id="status" text="{ model.status }" /> </mx:Canvas> Flex@Beach'10
  83. 83. <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> [Bindable] public var model:ContactFormPresentationModel; </mx:Script> <mx:Form> <mx:FormItem label="Id"> <mx:TextInput text="{ model.contact.id }" enabled="false" /> </mx:FormItem> <mx:FormItem label="First Name"> <mx:TextInput id="firstName" text="{ model.contact.firstName }" change="model.updateFirstName( firstName.text )" /> </mx:FormItem> <-- all of the other fields here --> </mx:Form> <controls:PictureInput id="picture" source=" { model.contact.pic }"/> <mx:Button bottom="26" left="12" label="Save" click="model.save()"/> <mx:Button bottom="26" left="72" label="Delete" click="model.remove()"/> <mx:Label id="status" text="{ model.status }" /> </mx:Canvas> ® Flex@Beach'10
  84. 84. <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> [Bindable] public var model:ContactFormPresentationModel; </mx:Script> <mx:Form> <mx:FormItem label="Id"> <mx:TextInput text="{ model.contact.id }" enabled="false" /> </mx:FormItem> <mx:FormItem label="First Name"> <mx:TextInput id="firstName" text="{ model.contact.firstName }" change="model.updateFirstName( firstName.text )" /> </mx:FormItem> <-- all of the other fields here --> </mx:Form> <controls:PictureInput id="picture" source=" { model.contact.pic }"/> <mx:Button bottom="26" left="12" label="Save" click="model.save()"/> <mx:Button bottom="26" left="72" label="Delete" click="model.remove()"/> <mx:Label id="status" text="{ model.status }" /> </mx:Canvas> ® Flex@Beach'10
  85. 85. Open file (InsyncMate3): src insync mate contacts ui presenters ContactPresentationModel.as Flex@Beach'10
  86. 86. public class ContactFormPresentationModel extends EventDispatcher { // ---------------------------------- private var _title:String; [Bindable(Event="titleChange")] public function get title():String { return _title; } // ----------------------------------- private var _status:String; [Bindable(Event="statusChange")] public function get status():String { return _status; } // ----------------------------------- private var _contact:Contact; [Bindable(Event="contactChange")] public function get contact():Contact { return _contact; } Flex@Beach'10
  87. 87. public class ContactFormPresentationModel extends EventDispatcher { // ---------------------------------- private var _title:String; [Bindable(Event="titleChange")] public function get title():String { return _title; } // ----------------------------------- private var _status:String; [Bindable(Event="statusChange")] public function get status():String { return _status; } // ----------------------------------- private var _contact:Contact; [Bindable(Event="contactChange")] public function get contact():Contact { return _contact; } Flex@Beach'10
  88. 88. ----------------------------------- private var dispatcher:IEventDispatcher; public function ContactFormPresentationModel(dispatcher:IEventDispatcher, contact:Contact) { this.dispatcher = dispatcher; _contact = contact; _title = contact.id > 0 ? contact.fullName: 'New Contact'; } // ----------------------------------- public function save():void { dispatcher.dispatchEvent( new ContactEvent( ContactEvent.SAVE, contact ) ); } // ----------------------------------- public function remove():void { dispatcher.dispatchEvent( new ContactEvent( ContactEvent.DELETE, contact ) ); } // ----------------------------------- public function contactSaved( event:ContactEvent ):void { if( event.contact == contact ) { _status = "Contact saved successfully"; dispatchEvent( new Event( "statusChange" ) ); }Flex@Beach'10
  89. 89. ----------------------------------- private var dispatcher:IEventDispatcher; public function ContactFormPresentationModel(dispatcher:IEventDispatcher, contact:Contact) { this.dispatcher = dispatcher; _contact = contact; _title = contact.id > 0 ? contact.fullName: 'New Contact'; } // ----------------------------------- public function save():void { dispatcher.dispatchEvent( new ContactEvent( ContactEvent.SAVE, contact ) ); } // ----------------------------------- public function remove():void { dispatcher.dispatchEvent( new ContactEvent( ContactEvent.DELETE, contact ) ); } // ----------------------------------- public function contactSaved( event:ContactEvent ):void { if( event.contact == contact ) { _status = "Contact saved successfully"; dispatchEvent( new Event( "statusChange" ) ); }Flex@Beach'10
  90. 90. ----------------------------------- private var dispatcher:IEventDispatcher; public function ContactFormPresentationModel(dispatcher:IEventDispatcher, contact:Contact) { this.dispatcher = dispatcher; _contact = contact; _title = contact.id > 0 ? contact.fullName: 'New Contact'; } // ----------------------------------- public function save():void { dispatcher.dispatchEvent( new ContactEvent( ContactEvent.SAVE, contact ) ); } // ----------------------------------- public function remove():void { dispatcher.dispatchEvent( new ContactEvent( ContactEvent.DELETE, contact ) ); } // ----------------------------------- public function contactSaved( event:ContactEvent ):void { if( event.contact == contact ) { _status = "Contact saved successfully"; dispatchEvent( new Event( "statusChange" ) ); }Flex@Beach'10
  91. 91. // Update functions ---------------------------------------------- public function updateFirstName( firstName:String ):void { contact.firstName = firstName; } // ----------------------------------- public function updateLastName( lastName:String ):void { contact.lastName = lastName; } // ----------------------------------- public function updateEmail( email:String ):void { contact.email = email; } // ----------------------------------- public function updatePhone( phone:String ):void { contact.phone = phone; } Flex@Beach'10
  92. 92. Open file (InsyncMate3): src insync mate contacts managers ContactsManager.as Flex@Beach'10
  93. 93. ContactsManager.as (InsyncMate3) public class ContactsManager extends EventDispatcher { private var editOpenContacts:Dictionary = new Dictionary( true ); private var newOpenContacts:Dictionary = new Dictionary( true ); // ------------------------------------------------------------------------ // property to store the last search keyword public var lastSearch:String = " "; // ------------------------------------------------------------------------ // Read-only public variable used to access the current contacts to show in list private var _contacts:ArrayCollection; [Bindable(event="contactsChanged")] public function get contacts():ArrayCollection { return _contacts; } // ------------------------------------------------------------------------ // Read-only public variable used to access the current contact (last selected contact) private var currentContact:Contact; public function getCurrentContact():Contact { return currentContact; } // ------------------------------------------------------------------------- // Stores given contacts and the current search keyword public function storeSearch( list:ArrayCollection, searchKey:String ):void { _contacts = list; Flex@Beach'10
  94. 94. ContactsManager.as (InsyncMate3) public class ContactsManager extends EventDispatcher { private var editOpenContacts:Dictionary = new Dictionary( true ); private var newOpenContacts:Dictionary = new Dictionary( true ); // ------------------------------------------------------------------------ // property to store the last search keyword public var lastSearch:String = " "; // ------------------------------------------------------------------------ // Read-only public variable used to access the current contacts to show in list private var _contacts:ArrayCollection; [Bindable(event="contactsChanged")] public function get contacts():ArrayCollection { return _contacts; } // ------------------------------------------------------------------------ // Read-only public variable used to access the current contact (last selected contact) private var currentContact:Contact; public function getCurrentContact():Contact { return currentContact; } // ------------------------------------------------------------------------- // Stores given contacts and the current search keyword public function storeSearch( list:ArrayCollection, searchKey:String ):void { _contacts = list; Flex@Beach'10
  95. 95. Open file (InsyncMate3): src insync mate contacts maps ContactMap.mxml Flex@Beach'10
  96. 96. ContactMap.mxml <LocalEventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/"> <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <Injectors target="{ ContactForm }"> <MethodInvoker generator="{ ContactsManager }" method="getCurrentContact" /> <ObjectBuilder generator="{ ContactFormPresentationModel }" cache="none" constructorArguments=" { [ scope.dispatcher, lastReturn ] }" /> <PropertyInjector targetKey="model" source="{ lastReturn }"/> </Injectors> <Injectors target="{ ContactFormPresentationModel }"> <ListenerInjector eventType="{ ContactEvent.SAVED }" method="contactSaved" /> </Injectors> </LocalEventMap> Flex@Beach'10
  97. 97. ContactMap.mxml <LocalEventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/"> <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <Injectors target="{ ContactForm }"> <MethodInvoker generator="{ ContactsManager }" method="getCurrentContact" /> <ObjectBuilder generator="{ ContactFormPresentationModel }" cache="none" constructorArguments=" { [ scope.dispatcher, lastReturn ] }" /> <PropertyInjector targetKey="model" source="{ lastReturn }"/> </Injectors> <Injectors target="{ ContactFormPresentationModel }"> <ListenerInjector eventType="{ ContactEvent.SAVED }" method="contactSaved" /> </Injectors> </LocalEventMap> Flex@Beach'10
  98. 98. ContactMap.mxml (InsyncMate3) <!-- ContactEvent.SAVE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <EventHandlers type="{ ContactEvent.SAVE }"> <RemoteObjectInvoker instance="{ services.contacts }" method="save" arguments=" { event.contact }"> <resultHandlers> <MethodInvoker generator="{ ContactsManager }" method="save" arguments="{ [resultObject, event.contact] }"/> <EventAnnouncer generator="{ SearchEvent }" dispatcherType="global" type=" { ContactEvent.REFRESH }"/> <EventAnnouncer generator="{ ContactEvent }" constructorArguments="{ [ContactEvent.SAVED, event.contact] }"/> </resultHandlers> </RemoteObjectInvoker> </EventHandlers> Flex@Beach'10
  99. 99. Version 3 Modules Flex@Beach'10
  100. 100. Open folder (InsyncMate3): src insync mate contacts ContactModule.mxml shared Flex@Beach'10
  101. 101. ContactModule.mxml <mx:Module xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> public function addTab( event:NavigatorEvent ):void { try { var childIndex:int = tabNavigator.getChildIndex( event.content ); tabNavigator.selectedIndex = childIndex; } catch( e:Error) { tabNavigator.addChild( event.content ); tabNavigator.selectedChild = event.content; } } public function removeTab( event:NavigatorEvent ):void { tabNavigator.removeChild( event.content ); } </mx:Script> <!-- EventMaps --> <maps:ContactMap dispatcher="{ this }"/> <!-- UI --> <mx:HDividedBox width="100%" height="100%"> <flexLib:SuperTabNavigator id="tabNavigator" width="100%" height="100%"/> <views:ContactList id="list" width="300"/> </mx:HDividedBox> Flex@Beach'10
  102. 102. ContactModule.mxml <mx:Module xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> public function addTab( event:NavigatorEvent ):void { try { var childIndex:int = tabNavigator.getChildIndex( event.content ); tabNavigator.selectedIndex = childIndex; } catch( e:Error) { tabNavigator.addChild( event.content ); tabNavigator.selectedChild = event.content; } } public function removeTab( event:NavigatorEvent ):void { tabNavigator.removeChild( event.content ); } </mx:Script> <!-- EventMaps --> <maps:ContactMap dispatcher="{ this }"/> <!-- UI --> <mx:HDividedBox width="100%" height="100%"> <flexLib:SuperTabNavigator id="tabNavigator" width="100%" height="100%"/> <views:ContactList id="list" width="300"/> </mx:HDividedBox> Flex@Beach'10
  103. 103. ContactModule.mxml <mx:Module xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> public function addTab( event:NavigatorEvent ):void { try { var childIndex:int = tabNavigator.getChildIndex( event.content ); tabNavigator.selectedIndex = childIndex; } catch( e:Error) { tabNavigator.addChild( event.content ); tabNavigator.selectedChild = event.content; } } public function removeTab( event:NavigatorEvent ):void { tabNavigator.removeChild( event.content ); } </mx:Script> <!-- EventMaps --> <maps:ContactMap dispatcher="{ this }"/> <!-- UI --> <mx:HDividedBox width="100%" height="100%"> <flexLib:SuperTabNavigator id="tabNavigator" width="100%" height="100%"/> <views:ContactList id="list" width="300"/> </mx:HDividedBox> Flex@Beach'10
  104. 104. Open file (InsyncMate3): src insync mate contacts maps ContactMap.mxml Flex@Beach'10
  105. 105. ContactMap.mxml <LocalEventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns=" http://mate.asfusion.com/"> <!-- SearchEvent.SEARCH ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <EventHandlers type="{ SearchEvent.SEARCH }" dispatcherType="global"> <RemoteObjectInvoker instance="{ services.contacts }" method=" getContactsByName" arguments=" { event.searchStr }"> <resultHandlers> <MethodInvoker generator="{ ContactsManager }" method=" storeSearch" arguments=" { [resultObject, event.searchStr] }"/> </resultHandlers> </RemoteObjectInvoker> </EventHandlers> <!-- ContactEvent.EDIT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <EventHandlers type="{ ContactEvent.EDIT }"> <MethodInvoker generator="{ ContactsManager }" method="openEditContact" arguments="{[ event.contact, ContactForm ]}" /> <EventAnnouncer generator="{ NavigatorEvent }" type="{ NavigatorEvent.ADD_CONTENT }" > <Property targetKey="content" source="{ lastReturn }"/> </EventAnnouncer> </EventHandlers> <!-- ContactEvent.ADD ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <EventHandlers type="{ ContactEvent.ADD }" dispatcherType="global"> <MethodInvoker generator="{ ContactsManager }" method="openNewContact" arguments="{ ContactForm }"/> Flex@Beach'10
  106. 106. ContactMap.mxml <LocalEventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns=" http://mate.asfusion.com/"> <!-- SearchEvent.SEARCH ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <EventHandlers type="{ SearchEvent.SEARCH }" dispatcherType="global"> <RemoteObjectInvoker instance="{ services.contacts }" method=" getContactsByName" arguments=" { event.searchStr }"> <resultHandlers> <MethodInvoker generator="{ ContactsManager }" method=" storeSearch" arguments=" { [resultObject, event.searchStr] }"/> </resultHandlers> </RemoteObjectInvoker> </EventHandlers> <!-- ContactEvent.EDIT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <EventHandlers type="{ ContactEvent.EDIT }"> <MethodInvoker generator="{ ContactsManager }" method="openEditContact" arguments="{[ event.contact, ContactForm ]}" /> <EventAnnouncer generator="{ NavigatorEvent }" type="{ NavigatorEvent.ADD_CONTENT }" > <Property targetKey="content" source="{ lastReturn }"/> </EventAnnouncer> </EventHandlers> <!-- ContactEvent.ADD ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <EventHandlers type="{ ContactEvent.ADD }" dispatcherType="global"> <MethodInvoker generator="{ ContactsManager }" method="openNewContact" arguments="{ ContactForm }"/> Flex@Beach'10
  107. 107. ContactMap.mxml <LocalEventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/"> <!-- SearchEvent.SEARCH ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <EventHandlers type="{ SearchEvent.SEARCH }" dispatcherType="global"> <RemoteObjectInvoker instance="{ services.contacts }" method=" getContactsByName" arguments=" { event.searchStr }"> <resultHandlers> <MethodInvoker generator="{ ContactsManager }" method=" storeSearch" arguments=" { [resultObject, event.searchStr] }"/> </resultHandlers> </RemoteObjectInvoker> </EventHandlers> <!-- ContactEvent.EDIT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <EventHandlers type="{ ContactEvent.EDIT }"> <MethodInvoker generator="{ ContactsManager }" method="openEditContact" arguments="{[ event.contact, ContactForm ]}" /> <EventAnnouncer generator="{ NavigatorEvent }" type="{ NavigatorEvent.ADD_CONTENT }" > <Property targetKey="content" source="{ lastReturn }"/> </EventAnnouncer> </EventHandlers> <!-- ContactEvent.ADD ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <EventHandlers type="{ ContactEvent.ADD }" dispatcherType="global"> <MethodInvoker generator="{ ContactsManager }" method="openNewContact" arguments="{ ContactForm }"/> Flex@Beach'10
  108. 108. ContactMap.mxml <LocalEventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/"> <!-- SearchEvent.SEARCH ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <EventHandlers type="{ SearchEvent.SEARCH }" dispatcherType="global"> <RemoteObjectInvoker instance="{ services.contacts }" method=" getContactsByName" arguments=" { event.searchStr }"> <resultHandlers> <MethodInvoker generator="{ ContactsManager }" method=" storeSearch" arguments=" { [resultObject, event.searchStr] }"/> </resultHandlers> </RemoteObjectInvoker> </EventHandlers> <!-- ContactEvent.EDIT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <EventHandlers type="{ ContactEvent.EDIT }"> <MethodInvoker generator="{ ContactsManager }" method="openEditContact" arguments="{[ event.contact, ContactForm ]}" /> <EventAnnouncer generator="{ NavigatorEvent }" type="{ NavigatorEvent.ADD_CONTENT }" > <Property targetKey="content" source="{ lastReturn }"/> </EventAnnouncer> </EventHandlers> <!-- ContactEvent.ADD ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <EventHandlers type="{ ContactEvent.ADD }" dispatcherType="global"> <MethodInvoker generator="{ ContactsManager }" method="openNewContact" arguments="{ ContactForm }"/> Flex@Beach'10 54
  109. 109. Learn more http://mate.asfusion.com Flex@Beach'10 57

×