0% found this document useful (0 votes)
89 views27 pages

Devnet Flex Trial Examples 10 Complex App - HTML Trackingid IOYQD

Sample project shows you how to connect a Flex application to server-side data. Applications can retrieve, update, add, and delete records in a database. Applications communicate with back-end servers using either socket connections or HT T P.

Uploaded by

Nevin Paul
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
89 views27 pages

Devnet Flex Trial Examples 10 Complex App - HTML Trackingid IOYQD

Sample project shows you how to connect a Flex application to server-side data. Applications can retrieve, update, add, and delete records in a database. Applications communicate with back-end servers using either socket connections or HT T P.

Uploaded by

Nevin Paul
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 27

Pro ducts

So lutio ns

Learning

Help

Do wnlo ads

Co mpany

Sto re

Search My suppo rt My shipments My cart Sign in

Adobe Developer Connection / Flex Developer Center /

Flex trial sample application


by Ado be

Modif ying dat a in a dat abase

Mo dif ie d 3 May 20 11 Page t o o ls Share o n Facebo o k Share o n Twitter Share o n LinkedIn Print Flex

PDFmyURL.com

This content requires Flash


To view this co ntent, JavaScript must be enabled, and yo u need the latest versio n o f the Ado be Flash Player.

Download the sample code and f iles (Z IP, 14. MB) You can also view the f ull source code by right-clicking the Flex application and selecting View Source.

Explanat ion
T his sample project shows you how to connect a Flex application to server-side data to retrieve, update, add, and delete records in a database. To look at the code, right-click on the SWF in the browser and select View Source or download the sample f iles and view the source f iles in a text editor or f ollow the instructions to import the Flash Builder FXP. Communicating with the server Flex applications cannot connect directly to a remote database. Instead, they communicate with back-end servers using either direct socket connections or more commonly, through HT T P. HT T P requests are made to a remote data service written in your f avorite web language (PHP, ColdFusion, Java, or any other server-side web technology) using one of the Flex f ramework's remote procedure call APIs: HT T PService, WebService, or RemoteObject. All three wrap Flash Player's HT T P connectivity, which in turn, uses the browser's HT T P library. With HT T PService, you make HT T P requests to JSP, PHP, CFM, or XML f iles; REST f ul web services; or other server f iles that returns text over HT T P. You specif y the endpoint URL, listener f unctions (the callback f unctions to be invoked when the HT T PService request returns a successf ul or unsuccessf ul response), and a data type f or the returned data (what type of data structure it should be translated into once received in the Flex application). You can specif y the data to be handled as raw text and assigned to a String variable or converted to XML, E4X, or plain old ActionScript objects. If you get back JSON, you can use the Adobe Flex corelib package of classes to deserialize the JSON objects into ActionScript objects. To make calls to SOAP based web services, you can use the HT T PService API or the more specialized WebService API, which automatically handles the serialization and deserialization of SOAP f ormatted text to ActionScript data types and vice versa. T he third option f or making remote procedure calls is to use the RemoteObject API. It makes a Flash Remoting request to a method of a server-side class (which can be a ColdFusion component) that
PDFmyURL.com

returns binary Action Message Format (AMF) over HT T P. You specif y an endpoint (which in this case is a server-side Flash Remoting class to handle the remoting request), a destination (the server-side class that has the methods you want to call), and listener f unctions to handle the responses. T he data translation between the client and server-side data types is handled automatically. T his sample project uses Flash Remoting whose binary data transf er f ormat enables applications to load data up to 10 times f aster than with the more verbose, text-based f ormats such as XML, JSON, or SOAP. To see a comparison of AMF to other text-based serialization technologies, see James Ward's Census RIA Benchmark application. Using Flash Remoting Flash Remoting is a combination of client and server-side f unctionality that together provides a call-andresponse model f or accessing server-side objects f rom Flash Platf orm applications as if they were local objects. It provides transparent data transf er between ActionScript and server-side data types, handling the serialization into binary Action Message Format (AMF), deserialization, and data marshaling between the client and the server. Flash Remoting uses client-side f unctionality built in to Flash Player and server-side f unctionality that must be installed on the application server. Flash Remoting is built in to some servers (like ColdFusion and Z end) but must be installed on other servers (as BlazeDS or LiveCycle Data Services on Java EE servers, WebORB or FluorineFX on .NET servers, the Z end Framework or amf php on PHP servers, and more). Setting up the server Let's start by taking a look at the server-side f iles. ColdFusion Flash Remoting is built in ColdFusion servers and little setup is necessary. You need to make sure that Flash Remoting is enabled in the ColdFusion Administrator (Data & Services > Flex Integration > Enable Flash Remoting support) and then in your ColdFusion components, specif y an access of remote f or the f unctions you want to access f rom Flex applications. T his sample project calls methods of EmployeeService.cf c located in /wwwroot/TestDrive/services/.

<cfcomponent output="false"> <cffunction name="getEmployees" output="false" access="remote" returntype="Query">


PDFmyURL.com

<cfset var qGetEmployees=""> <cfquery name="qGetEmployees" datasource="testdrive_db"> SELECT *FROM employees </cfquery> <cfreturn qGetEmployees> </cffunction> <!-- other functions --> </cfcomponent>

T he f iles f or conf iguring Flash Remoting f iles are located in /ColdFusion/wwwroot/WEB-INF/f lex/. T he main conf iguration f ile, services-conf ig.xml, def ines channels to specif y how communication should take place between the client and server, including the protocol to use (f or example, AMF over HT T P or HT T PS), the endpoints (the classes to handle and route the calls on the server), and other inf ormation f or f inetuning the calls (like specif ying if query columns names and structure keys should be translated into ActionScript with lowercase or uppercase property names). You set the case by modif ying the <property-case> tag as shown below.

<property-case> <!-- cfc property names --> <force-cfc-lowercase>true</force-cfc-lowercase> <!-- Query column names --> <force-query-lowercase>true</force-query-lowercase> <!-- struct keys --> <force-struct-lowercase>true</force-struct-lowercase> </property-case>

T he services-conf ig.xml f ile also includes a ref erence to the remoting-conf ig.xml f ile, which is where you can def ine destinations, or mappings to specif ic ColdFusion components you want to call f rom Flex. (Af ter changes to the conf iguration f iles, you must restart the server.) By def ault, remoting-conf ig.xml contains one def ault destination (with an id of ColdFusion) that has its source property set to a wildcard so it can be used f or any Flash Remoting calls to any ColdFusion components.

PDFmyURL.com

<destination id="ColdFusion"> <channels> <channel ref="my-cfamf"/> </channels> <properties> <source>*</source> </properties> </destination>

To make a call f rom Flex with RemoteObject, you specif y a destination of ColdFusion and a source of TestDrive.services.employeeService, the f ully qualif ied name of the ColdFusion component that you want to call f rom the webroot. You can also add named destinations to remoting-conf ig. For example, you could create a destination called employeeService that points to that same CFC:

<destination id="employeeService"> <properties> <source>TestDrive.services.EmployeeService</source> </properties> </destination>

... and then when making calls f rom Flex, you would specif y a destination of employeeService (instead of ColFusion) and no source (because it is now included in the destination) Java To use Flash Remoting with Java, you need to install an implementation of Flash Remoting on the server. Adobe provides the open-source BlazeDS or the commercial LiveCycle Data Services. T his sample uses BlazeDS and the BlazeDS f iles (JAR f iles and conf iguration f iles) are included in the Test Drive WAR f ile along with the Java classes to call f rom the Flex application. For more details, read the Flex and Java technology overview and the architecture overview. T his sample project calls methods of EmployeeService located in the testdrive webapp: /testdrive/WEBPDFmyURL.com

INF/classes/services/. (T he source f iles are also included f or ref erence in /testdrive/webapps/WEBINF/src/services/.) It uses a typical assembler design pattern and manipulates instances of an Employee data transf er object, which we will map to a corresponding client-side ActionScript object f or passing data back and f orth between the client and server. To be called f rom Flex, the Java class must have a no argument constructor.

package services; import java.util.List; import services.EmployeeDAO; import services.Employee; public class EmployeeService { public EmployeeService() { } public List getEmployees() { EmployeeDAO dao = new EmployeeDAO(); return dao.getEmployees(); } //more methods... }

T he f iles f or conf iguring Flash Remoting f iles are located in /testdrive/WEB-INF/f lex/. T he main conf iguration f ile, services-conf ig.xml, def ines channels to specif y how communication should take place between the client and server, including the protocol to use (f or example, AMF over HT T P or HT T PS), the endpoints (the classes to handle and route the calls on the server), and other inf ormation f or f inetuning the calls. T he services-conf ig.xml f ile also includes a ref erence to the remoting-conf ig.xml f ile, which is where you def ine destinations, or mappings to the specif ic Java classes you want to call f rom Flex. Here is the destination used f or the sample projects called employeeService:

<destination id="employeeService"> <properties> <source>services.EmployeeService</source>


PDFmyURL.com

<scope>application</scope> </properties> </destination>

To make a call f rom Flex with RemoteObject, you specif y a destination of employeeService. PHP To use Flash Remoting with PHP, you need to install an implementation of Flash Remoting on the server. T his sample uses the Z end Framework. You must install the f ramework and then create a PHP f ile (in this sample, gateway.php) to use the f ramework and handle all the requests f rom Flex, including passing them to the appropriate PHP classes, handling all the data translation and serialization, and more. If you use the Create Data Service wizard in Flash Builder to create a data service to connect to a PHP class, the Z end f ramework is automatically installed on your server (if it is not already) and gateway.php and an amf -conf ig.ini f ile created and placed on the server along with the SWF. Although this sample does not use service f iles created with the Flash Builder Data Service wizard, it does use the gateway.php and amf conf ig.ini f iles it creates. (T he Flex Test Drive has a tutorial f or creating the service with the wizard.) T his sample project calls methods of EmployeeService located in /htdocs/TestDrive/services/.

<?php class EmployeeService { public function getEmployees() { $stmt = mysqli_prepare($this->connection,"SELECT *FROM employees"); //more code return $rows; } //more methods }

You specif y directories that contain PHP classes to call f rom Flex in the amf -conf ig.ini f ile.

;more code
PDFmyURL.com

amf.directories[]=TestDrive/servicesc

To make a call f rom Flex with RemoteObject, you specif y a destination of zend, an endpoint of gateway.php, and a source of EmployeeService, the name of the PHP class to call. Creating a RemoteObject Now that we've looked at the server-side f iles, let's see how to call them f rom Flex. T he f irst step is to def ine an instance of the RemoteObject class either in the Script block with ActionScript or in the Declarations tag with MXML; they are equivalent. T he Declaration tag provides a way to def ine non-visual objects with MXML. (T he green color of the tag indicates it is a compiler tag associated with compiler instructions and not an instance of a class.) Depending upon what server you are using, the RemoteObject will have slightly dif f erent properties specif ied (the destination and possibly the source and/or endpoint). For ColdFusion and Java, the endpoint is set dynamically using the services-conf ig.xml f ile and f or ColdFusion, a source needs to be set if the def ault ColdFusion destination is used. Af ter substituting the values f rom the constants set in the Script block of the sample code, the RemoteObject tag will look like one of these.

<fx:Declarations> <!-- ColdFusion--> <s:RemoteObject id="employeeService " destination="ColdFusion" source="TestDrive.services.Emplo fault="employeeService_faultHandler(event)"/> <!-- PHP --> <s:RemoteObject id="employeeService " destination="zend" source="EmployeeService" endpoint="gat <!--Java--> <s:RemoteObject id="employeeService " destination="employeeService" showBusyCursor="true" fa </fx:Declarations>

You call a method of the server-side class by calling that method on this client-side object, f or example, employeesService.getEmployees(). Remote procedure calls are asynchronous so you also need to specif y listener f unctions, the callback f unctions to be invoked when a request returns a successf ul or unsuccessf ul response. For Flex remote
PDFmyURL.com

f unctions to be invoked when a request returns a successf ul or unsuccessf ul response. For Flex remote procedure calls, you register to listen f or result and fault events. Because a data service of ten has multiple methods that can be called and they can be called at dif f erent times in the application, the callback f unctions are usually specif ied on a per call basis instead of on the service object. In this sample, a fault handler is specif ied f or the RemoteObject but no result handler. T his fault handler will be used f or all service calls that do not have their own f ault handler specif ied. T he handler uses the Flex Alert component (which has a static show() method), to display a popup with the f ault message. T he FaultEvent object has a property called fault that is equal to an instance of the Fault class that has properties faultString and faultDetail.

import mx.controls.Alert; import mx.rpc.events.FaultEvent; protected function employeeService_faultHandler(event:FaultEvent):void { Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail,"Error"); }

Note: Instead of using the RemoteObject class directly as in this sample, you can also use Flash Builder's Create Data Service wizard to create a data service and then call methods of a generated service class that wraps the RemoteObject class. Flash Builder introspects the server-side class f ile and creates a corresponding client-side class with the same operations. (For this introspection and code generation to occur, RDS must be enabled on your server.) If the server returns strongly typed objects (which is the case f or the Java classes in this sample), ActionScript classes are created that map to the corresponding objects manipulated by the methods of the class. If the server returns general objects (which is the case f or the PHP class and CFC in this sample), you can conf igure the data service to create typed ActionScript objects whose properties match those f or the general objects returned f rom the server. Of course, you can also write your PHP classes and CFC methods to return strongly typed objects instead of general objects as well. Af ter creation, the data service, its methods, its argument types, and its return types are displayed in the Data/Services view and methods can be dragged and dropped on components in the application to add them. T he Flex Test Drive tutorials create and use data services created with the Flash Builder Data Service wizard. Retrieving data Next, let's look at the calls to the server. We want to retrieve the employee and department data on
PDFmyURL.com

application startup. To do this, you usually specif y an event handler f or the Application object's initialize or creationComplete events. Every Flex component has a series of events that are broadcast as the component is created, f rom the time it is instantiated until the time it is drawn on the Flash Player drawing surf ace. T he initialize event is broadcast af ter the component has been created and all of its properties are set and those of its subobjects. creationComplete is broadcast later af ter the component and all its subobjects also have sizes and positions. Use creationComplete if any of the code ref erences any sizes or positions. In the sample code, a handler is specif ied f or the Application's initialize event:

<s:Application initialize="init()" ...>

... and inside the handler, the getEmployees() and getDepartments() methods of the service object are called.

protected function init():void { getEmployeesResult.token = employeeService.getEmployees(); getDepartmentsResult.token = employeeService.getDepartments(); }

When this code is executed, Flash Player makes a call to the server. T his happens asynchronously in the background; the user can still interact with the application. When you make a service call, you need to specif y what Flash Player should do when it gets a result or error back f rom the server. A fault handler was specif ied f or the data service itself and will be used to display errors returned f rom calls to any of its operations in a popup box. Using call responders to specify callbacks To handle successf ul results, CallResponder objects are declared f or each of the calls.

PDFmyURL.com

<fx:Declarations> <s:CallResponder id="getEmployeesResult" .../> <s:CallResponder id="getDepartmentsResult"/> (...) </fx:Declarations>

T hese need to be associated with the corresponding service call. When a service call is initiated, an instance of the AsyncToken class is created. To associate the CallResponder object with the service call, you set the CallResponder's token property equal to the AsyncToken generated at the time the service call is made. When data is returned f rom the server, it is handled by that CallResponder.

getEmployeesResult.token=employeeService.getEmployees();

A CallResponder object has a lastResult property that automatically gets populated with the data when it is returned to Flash Player f rom the server. It can be easily used by binding a control to it. In the application, the dataProvider property of a DataGrid component is bound to the lastResult property of the getDepartmentsResult CallResponder object. Whenever the value of getDepartmentsResult.lastResult changes, the DataGrid's dataProvider property is updated and the DataGrid repopulates itself with the new data.

<s:DataGrid id="deptDg" dataProvider="{getDepartmentsResult.lastResult}" ...> <s:columns> <s:ArrayList> <s:GridColumn headerText="Name" dataField="name" /> <s:GridColumn headerText="ID" dataField="id" width="40"/> <s:GridColumn headerText="Manager" dataField="manager" width="170"/> <s:GridColumn dataField="budget" headerText="Budget" width="155"/> <s:GridColumn dataField="actualexpenses" headerText="Expenses" width="155"/> </s:ArrayList> </s:columns> </s:DataGrid>
PDFmyURL.com

By def ault, one column is created f or each of the f ields in the objects used to populate the DataGrid. You control what properties to display and in what order by setting the columns property equal to an ArrayList of GridColumn objects. For each DataGridColumn object, you specif y what property it should display (dataField), the title f or the column (headerText), its size, and more. Using the CallResponder lastResult property works f ine if you just want to bind the results to a component as shown here, but many times you will want to execute some code when the results are returned. To do this, you register to listen f or the result or fault events f or the CallResponder. In the sample, a result handler is registered f or the getEmployeesResult CallResponder.

<s:CallResponder id="getEmployeesResult" result="getEmployeesResult_resultHandler(event)"/>

... and the getEmployeesResult_resultHandler() def ined. Handling return data T his application manipulates employee data. When you bind controls to collections of objects (as we just saw in the deptDg DataGrid and will see next f or the empDg DataGrid), the data should be strored in a Flex collection class. For example, instead of storing the employee data objects in an Array (a top level data type in Flash Player), you should use an ArrayList or ArrayCollection. T he ArrayList and ArrayCollection classes basically wraps an Array so that when any value in any position of the array changes, an event is broadcast and any controls bound to it will be updated. If the objects were stored in an Array, even if it was made bindable, events would be broadcast only when the value of the entire array changed, f or example, if it went f rom null to a value or was set to an entirely dif f erent value. Unlike an ArrayList, an ArrayCollection can also be sorted, f iltered, and traversed with a cursor. In this application, an employees ArrayCollection is def ined in the Declarations block:

<s:ArrayCollection id="employees"/>

PDFmyURL.com

... which is equivalent to setting a public, bindable variable in ActionScript:

[Bindable]public var employees:ArrayCollection;

T he dataProvider property of the empDg DataGrid is bound to this collection.

<mx:DataGrid id="empDg" dataProvider="{employees}" ...>

Inside this collection, we want to store strongly typed, bindable Employee objects, not general Objects. T his way we will get code-hinting when manipulating these objects and compiler and runtime property and property type checking. T hese objects will also be bindable, so if any of their properties change, an event will be broadcast and any objects bound to it updated. If you look in the valueObjects f older, you will see an Employee class def inition.

package valueObjects { [Bindable] //if server was returning typed objects like for java, ///[RemoteClass(alias="services.Employee")] public class Employee { public var id:uint; public var firstname:String; public var lastname:String; //other property declarations public function Employee() { } } }
PDFmyURL.com

If the server-side class returns strongly typed objects (as does the Java class in this sample), you need to include a RemoteClass metadata tag that maps this ActionScript class to the corresponding class on the server.

[RemoteClass(alias="services.Employee")]

T his is the crucial inf ormation needed by Flash Player so it can map the server-side objects to the correct client-side objects automatically. In this case, the getEmployeeResult_resultHandler() only needs to populate the employees ArrayCollection with the data returned f rom the server because the data has already been translated to an ArrayCollection of Employee objects.

protected function getEmployeesResult_resultHandler(event:ResultEvent):void { employees=event.result as ArrayCollection; }

T he data returned f rom a server-side method call is stored in the result property of the event object that is passed to the result event handler. T he employees variable is data typed as an ArrayCollection but the result property of the event object is data typed as a general Object, so you have to cast event.result to an ArrayCollection to assign it to employees. To see what types of ActionScript objects the returned server-side data objects are converted to, place a breakpoint inside the result handler and debug the application. You can also look at tables of the data type mappings f or ActionScript and Java, ActionScript and PHP, or ActionScript and ColdFusion. If Employee objects are not returned f rom the server (as is the case f or the PHP class and CFC in this sample), getEmployeesResult_resultHandler() needs to create this collection of Employee objects manually. For PHP, you get an Array of Objects back f rom the server and f or ColdFusion, an ArrayCollection of Objects. To convert the Objects into Employee objects, you need to loop through the collection, creating a new Employee instance f or each item and populating its properties with the
PDFmyURL.com

corresponding properties of the general Object, and then adding that Employee object to the collection. You could explicitly write each property assignment: emp.id=data[i].id; emp.f irstname=data[i].f irstname; emp.lastname=data[i].lastname; //do the same f or all properties ... but this code instead uses the describeType() method (in the f lash.utils package). describeType() returns an XML object that contains an accessor element (which has name, access, type, and declaredBy attributes) f or each of object's properties. T his is the ActionScript implementation of ref lection. For ColdFusion, the getEmployeesResult_resultHandler() appears as shown here.

protected function getEmployeesResult_resultHandler(event:ResultEvent):void { var data:ArrayCollection=event.result as ArrayCollection; for(var i:uint=0; i<data.length; i++) { var emp:Employee=new Employee(); for each(var field:XML in describeType(emp)..accessor){ emp[field.@name]=data[i][field.@name]; } employees.addItem(emp); } }

T he ArrayColletion addItem() method is used to add the new employee to the employees ArrayCollection. T he handler is slightly dif f erent f or PHP because you get an Array instead of an ArrayCollection back f rom the server.

PDFmyURL.com

protected function getEmployeesResult_resultHandler(event:ResultEvent):void { var data:ArrayCollection=new ArrayCollection(event.result as Array); for(var i:uint=0; i<data.length; i++) { var emp:Employee=new Employee(); for each(var field:XML in describeType(emp)..accessor){ emp[field.@name]=data[i][field.@name]; } employees.addItem(emp); } }

Displaying details When the user selects an employee in the DataGrid, that employee's details are displayed beneath it. In the Declarations block, you'll see an employee variable def ined of type Employee (that is bindable by def ault).

<valueObjects:Employee id="employee"/>

Beneath the Declarations block, you'll see a Binding tag:

<fx:Binding source="empDg.selectedItem as Employee" destination="employee"/>

T his is just another way to create a binding between two variables without using {} in an MXML tag. Whenever the selectedItem property of empDg changes, the employee variable is updated. As well, there is code to listen f or the DataGrid's selectionChange event:

<s:DataGrid id="empDg" dataProvider="{employees}" includeIn="EmployeeAdd,EmployeeDetails,EmployeeUpdate,Employees"


PDFmyURL.com

selectionChange="empDg_selectionChangeHandler(event)" ...>

Inside the selectionChange handler, you switch to the application's EmployeeDetails state:

protected function empDg_selectionChangeHandler(event:GridSelectionEvent):void{ currentState="EmployeeDetails"; }

... that includes a Form container that has one Label control f or each of the employee object's properties.

<s:Form includeIn="EmployeeDetails" x="63" y="325"> <s:FormItem label="Last Name"> <s:Label id="lastnameLabel" text="{employee.lastname}"/> </s:FormItem> <s:FormItem label="First Name"> <s:Label id="firstnameLabel" text="{employee.firstname}"/> </s:FormItem> (...) </mx:Form>

T he employee details will be displayed in the Label controls in the Form. A Flex Form container is purely a layout container, helping to easily line up multiple controls that have labels in f ront of them; it has no other purpose like in an HT ML f orm. When you send data to the server which we will look at next, you specif y explicity what objects to send; they have nothing to do with Form components. Now that we have seen how to retrieve and display data f rom the server, let's look at how to modif y this data on the server, updating, adding, and deleting records in the database. You may want to go look at your application server's class f ile (or CFC) now to f amiliarize yourself with the methods it contains bef ore looking at the code to call these methods. If you installed the f iles, you can look at the source code on your server. Otherwise, you can right-click the SWF in the browser, select View Source, and browse to the appropriate PHP class, Java class, or CFC.
PDFmyURL.com

Using the DataGrid to update data One way to let users update the data is to make the DataGrid editable and then to send the changes to the server. You make the DataGrid editable by setting its editable property to true and then registering to listen f or its gridItemEditorSessionSave event which is broadcast when the user makes changes to a cell value.

<s:DataGrid id="empDg" dataProvider="{employees}" editable="true" gridItemEditorSessionSave="empDg_gridItemEditorSessionSaveHandler(event)" ...>

Inside the handler, you need to send the modif ied Employee instance to the server: call the updateEmployee() method and pass to it the selected item in the DataGrid.

employeeService.updateEmployee(employee);

For ColdFusion, you need to modif y this slightly. When you pass an object to a Flash Remoting request, it is treated as a group of named arguments and passed to the CFC method as individual arguments, not as a single object argument. To actually pass a single object as an argument, you must create an Object instance with the name of the argument expected by the CFC, in this case an argument called item, and pass that to the server-side method. T he {} here are are an ActonScript short hand notation f or creating an Object; multiple name/value pairs would be separated by commas.

employeeService.updateEmployee({item:employee});

In this case, you're not going to do anything af ter the data is successf ully updated so you don't need to specif y a CallResponder to handle the results. In this application, updates are sent to the server every time the user changes data in one DataGrid cell. If a lot of changes are going to be made, you may want to wait and submit all changes to the server at once.
PDFmyURL.com

Using a form to update data Only some of the employee data is displayed in the DataGrid, so you may also want to provide a f orm f or the user to modif y all of the employee data. When an employee is selected and the EmployeeDetails state displayed, an update button is enabled.

<s:Button id="updateBtn" includeIn="EmployeeAdd,EmployeeDetails,EmployeeUpdate" label="Update" enabled.EmployeeAdd="false" enabled.EmployeeUpdate="false" click="updateBtn_clickHandler(event)" .../>

When the user clicks this button, the application switches to its EmployeeUpdate state:

protected function updateBtn_clickHandler(event:MouseEvent):void{ currentState="EmployeeUpdate"; }

... that has a Form containing one TextInput control f or each of the employee properties that can be updated.

<s:Form includeIn="EmployeeAdd,EmployeeUpdate" defaultButton="{button}"...> <s:FormItem label="Last Name"> <s:TextInput id="lastnameTextInput" text="{employee.lastname}"/> </s:FormItem> <s:FormItem label="First Name"> <s:TextInput id="firstnameTextInput" text="{employee.firstname}"/> </s:FormItem> <!-- more FormItem controls --> <s:FormItem> <s:Button id="button" label="Add" click="button_clickHandler(event)" label.EmployeeUpdate=" </s:FormItem> </s:Form>
PDFmyURL.com

When the user clicks this button in the Form container, the employee object is updated with the values the user entered in the input controls and then passed to the data service's updateEmployee() method.

protected function button_clickHandler(event:MouseEvent):void { employee.lastname = lastnameTextInput.text; employee.firstname = firstnameTextInput.text; employee.title = titleTextInput.text; //code to set the rest of the properties if(employee.id==0){ //for Java and PHP createEmployeeResult.token = employeeService.createEmployee(employee); //for CF, createEmployeeResult.token = employeeService.createEmployee({item:employee}); } else{ //for Java and PHP updateEmployeeResult.token = employeeService.updateEmployee(employee); //for CF, updateEmployeeResult.token = employeeService.updateEmployee({item:employee}); } }

Similar f unctionionality will be used to add a new employee next, so this f unction has been written to handle both cases. If an existing employee is being updated, employee.id will be non-zero, so the server-side updateEmployee() method is called. Otherwise, the createEmployee() method is called. As bef ore, the code f or ColdFusion is slightly dif f erent to pass an object to a server-side method. In this case, we do want to do something af ter the data has successf ully been sent to the server, so a new CallResponder is def ined with a result handler:

PDFmyURL.com

<s:CallResponder id="updateEmployeeResult" result="updateEmployeeResult_resultHandler(event)"/>

... and the service call assigned to the CallResponder's token property.

updateEmployeeResult.token=employeeService.updateEmployee(employee);

In the result handler, the application switches to its EmployeeDetails state and shows the details f or the modif ied employee.

protected function updateEmployeeResult_resultHandler(event:ResultEvent):void { currentState="EmployeeDetails"; }

Using the form to add data Similar code is used to add a new employee to the database. When an employee is selected, an add button is enabled.

<s:Button id="addBtn" label="Add" click="addBtn_clickHandler(event)" includeIn="EmployeeAdd,EmployeeDetails,EmployeeUpdate,Employees" enabled.EmployeeAdd="false" enabled.EmployeeUpdate="false" .../>

When the user clicks this button, the application switches to its EmployeeAdd state, which shows the same f orm as used to update an employee, but now the submit button is labeled Add instead of Update.

protected function addBtn_clickHandler(event:MouseEvent):void {


PDFmyURL.com

currentState="EmployeeAdd"; employee=new Employee(); }

Using the form to add data Similar code is used to add a new employee to the database. When an employee is selected, an add button is enabled.

<s:Button id="addBtn" label="Add" click="addBtn_clickHandler(event)" includeIn="EmployeeAdd,EmployeeDetails,EmployeeUpdate,Employees" enabled.EmployeeAdd="false" enabled.EmployeeUpdate="false" .../>

When the user clicks this button, the application switches to its EmployeeAdd state, which shows the same f orm as used to update an employee, but now the submit button is labeled Add instead of Update.

protected function addBtn_clickHandler(event:MouseEvent):void { currentState="EmployeeAdd"; employee=new Employee(); }

T he employee object is also set equal to a new Employee instance (employee could currently contain the employee selected in the DataGrid) so the input controls in the Form container that are bound to it will all be set to the Employee class's def ault values. T he same handler is called when the user clicks the button in the f orm:

<s:FormItem> <s:Button id="button" label="Add" click="button_clickHandler(event)" label.EmployeeUpdate="Upd </s:FormItem>


PDFmyURL.com

... which populates employee with the data f rom the input controls and now in this case, employee.id will be zero so employee is passed to the data service's createEmployee() method.

protected function button_clickHandler(event:MouseEvent):void { employee.lastname = lastnameTextInput.text; employee.firstname = firstnameTextInput.text; employee.title = titleTextInput.text; //code to set the rest of the properties if(employee.id==0){ //for Java and PHP createEmployeeResult.token = employeeService.createEmployee(employee); //for CF, createEmployeeResult.token = employeeService.createEmployee({item:employee}); } else{ //for Java and PHP updateEmployeeResult.token = employeeService.updateEmployee(employee); //for CF, updateEmployeeResult.token = employeeService.updateEmployee({item:employee}); } }

To handle results, a new CallResponder is def ined with a result handler:

<s:CallResponder id="createEmployeeResult" result="createEmployeeResult_resultHandler(event)"/>

... and the service call assigned to the CallResponder's token property.
PDFmyURL.com

createEmployeeResult.token=employeeService.createEmployee(employee);

Af ter the data is added successf ully to the database, the EmployeeDetails state is shown with the details f or this new employee.

protected function createEmployeeResult_resultHandler(event:ResultEvent):void { currentState="EmployeeDetails"; // more code }

At this point the new employee is saved in the database, but not in the collection of data being displayed in the DataGrid. You need to assign the newly generated id to employee and add employee to the data displayed in the DataGrid. If you look in the TestDrive server-side service f ile, you will see that the createEmployee() method returns an integer equal to the id of the new employee inserted in the database. T he data returned f rom a server-side method call is stored in the result property of the event object that is passed to the result event handler. T he id property of employee is data typed as an integer and the result property of the event object is data typed as a general Object, so you have to cast event.result to an integer to set id equal to it.

employee.id=event.result as int;

You use the addItem() method to add the new employee to the employees ArrayCollection.

employees.addItem(employee);
PDFmyURL.com

Note: In this example, you are writing code to update both the server-side data (stored in the database) and the client-side data (stored in the DataGrid dataProvider). Flash Builder also has a data management f eature you can use to help synchronize client and server-side data. T hen, you select it in the DataGrid:

empDg.setSelectedIndex (employees.getItemIndex(employee));

... and then scroll to it so it is displayed:

empDg.ensureCellIsVisible(empDg.selectedIndex);

T he result event handler f or adding an employee appears as shown here.

protected function createEmployeeResult_resultHandler(event:ResultEvent):void { currentState="EmployeeDetails"; employee.id=event.result as int; employees.addItem(employee); empDg.setSelectedIndex(employees.getItemIndex(employee)); empDg.ensureCellIsVisible(empDg.selectedIndex); }

Deleting data T he last thing to look at is how to delete an employee f rom the database. T he process is very similar to those f or adding and updating. When an employee is selected, a delete button is enabled.

<s:Button id="deleteBtn" click="deleteBtn_clickHandler(event)"


PDFmyURL.com

enabled.EmployeeAdd="false" includeIn="EmployeeAdd,EmployeeDetails,EmployeeUpdate" label="Delete" enabled.EmployeeUpdate="true"/>

When the user clicks this button, the server-side deleteEmployee() method is called.

protected function deleteBtn_clickHandler(event:MouseEvent):void { deleteEmployeeResult.token = employeeService.deleteEmployee(employee.id); }

To handle results, a new CallResponder is def ined with a result handler:

<s:CallResponder id="deleteEmployeeResult" result="deleteEmployeeResult_resultHandler(event)"/>

... and the service call assigned to the CallResponder's token property.

deleteEmployeeResult.token=employeeService.deleteEmployee(employee.id);

T he server-side method expects one argument, the id of the employee to delete. In the result handler, the employee is removed f rom the employees ArrayCollection using its removeItemAt() method and the application is switched to its Employees state (there is no longer any employee selected to show details f or).

protected function deleteEmployeeResult_resultHandler(event:ResultEvent):void { employees.removeItemAt(empDg.selectedIndex);


PDFmyURL.com

currentState="Employees"; }

Back to top

+ T his work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Permissions beyond the scope of this license, pertaining to the examples of code included within this work are available at Adobe.

Cho o se yo ur re gio n

Care e rs Pe rm issio ns and t rade m arks EULAs Re po rt piracy Co nt act Ado be

Se curit y

Co pyright 20 11 Ado be Systems Inco rpo rated. All rights reserved. Use o f this website signifies yo ur agreement to the Te rm s o f Use and Online Privacy Po licy (updated 07-14-2009) .

PDFmyURL.com

You might also like