Professional Documents
Culture Documents
Contents
Chapter 1: Import a service and bind data to application components
Create the application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Create a ColdFusion service that returns localized strings ............................................................... 5
(Optional) Test the ColdFusion service ................................................................................. 6
Connect to the ColdFusion service ..................................................................................... 9
Examine the generated code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3 Click Next. Verify your ColdFusion server configuration and click Validate Configuration.
4 Click Finish.
The Flash builder source editor opens to Hello.mxml.
5 If Design mode is not selected, select Design to switch to Design mode of the editor.
6 In the Components View, make sure that the Controls folder is open. Scroll the controls to find the Label control.
7 Drag a Label component from the Components View to the design area.
8 Double-click the Label component. Replace the default text with Hello.
9 In the Properties view, modify the appearance of the text. With the Label component selected, specify the following:
Font Size 24
10 Click the Font color box and specify #ff0000 to change the text to Red.
11 Save the file. Click the Run button to run the application.
Run button
<cfcomponent>
<cffunction name="getMessage" access="remote" returntype="string">
<cfset message = "Hello from CF!">
<cfreturn message>
</cffunction>
<cfswitch expression="#locale#">
<cfcase value="en">
<cfset message = "Hello from CF!"/>
</cfcase>
<cfcase value="es">
<cfset message = "Hola de CF!"/>
</cfcase>
<cfcase value="ne">
<cfset message = "Namaskar CF bata!"/>
</cfcase>
<cfdefaultcase>
<cfthrow message="Unknown locale code"/>
</cfdefaultcase>
</cfswitch>
<cfreturn message>
</cffunction>
<cffunction name="getLocales" returnType="array" access="remote">
<cfset codes = listToArray("en,es,ne")/>
<cfreturn codes>
</cffunction>
</cfcomponent>
Testing getLocalizedMessage("es")...
<cfinvoke component="HelloService" method="getLocalizedMessage" locale="es"
returnvariable="message"/>
<p> Result: <cfdump var="#message#"/> </p>
2 Save helloservicetest.cfm in the same folder as HelloService.cfc, and call the script from a web browser:
http://localhost:8500/HelloCF/helloservicetest.cfm
If there is an error in the service, ColdFusion displays detailed information about the error.
You can also enable Robust Exception Information for the ColdFusion server to get detailed debugging output.
3 Add trace statements to the service.
In the ColdFusion Administrator, enable debugging and logging.
Add ColdFusion trace statements as necessary to debug your service. For example, add the following line in
helloservicetest.cfm:
Testing getLocalizedMessage()...
<cfinvoke component="HelloService" method="getLocalizedMessage" locale="es"
returnvariable="message"/><p> Result: <cfdump var="#message#"/>
<cftrace category="getLocalizedMessage End" inline="yes" var="message"
text="GetLocalizedMessage call has completed">
Call the script from a web browser to view the debugging output. You can also inspect the ColdFusion log files.
Note: You can also test a service after importing the service into Flash Builder. Use Test Operation, which is available
from the Data/Service view.
3 Click Browse and navigate to the HelloService.cfc you previously created. Flash Builder names the service
HelloService.
The Data Service View provides a picture of remote services. This view becomes useful when you configure types
for data returned by a service call.
5 Select the Label component in the design area. From the context menu for the Label component, select Bind to Data.
Select OK to replace the current text with the text returned from a service operation.
Flash Builder provides various ways to bind data to a selected component. In addition to the the context menu,
you can bind to data from Properties view. You can also select Bind to Data from the Flash Builder Data menu.
6 In the Bind to Data dialog, make sure that New Service Call is selected. For Operation select
getLocalizedMessage. Click OK.
Flash Builder switches the editor to Source mode, highlighting the parameter to getLocalizedMessage().
7 Type "es" for the parameter value for getLocalizedMessage(). Switch to Design mode of the editor.
The Label component displays the message retrieved from the HelloService.
Event handlers
Flex uses event handlers to trigger a service call.
Flex code is not processed “top to bottom,” as in server templates. Instead, applications built with Flex listen for events
to trigger responses.
By default, Flex uses the creationComplete event on a component to trigger a service call.
Examine the Label component in the HelloCF.mxml source code:
<s:Label x="70" y="60"
text="{getLocalizedMessageResult.lastResult}"
fontWeight="bold" fontSize="24" fontStyle="italic"
color="#FF0000" id="label"
creationComplete="label_creationCompleteHandler(event)"/>
The creationComplete event fires after the application creates the component. For this Label component,
creationComplete calls an event handler that Flash Builder generated for the event. Examine the code for the event
handler, which is placed inside a Script block:
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import mx.controls.Alert;
]]>
</fx:Script>
The creationComplete event handler calls the getLocalizedMessage() operation from the ColdFusion service. It
passes the parameter “es”, which you specified earlier in the source code.
You can use other events, such as a Click event on a button or a selectionChange event of a list, to trigger service
calls.
When you imported the HelloService service, Flex created the HelloService class. This class contains methods to call
the getLocales(), and getLocalizedMessage operations of the service.
The CallResponder, identified by the getLocalizedMessageResult id, provides access to the returned data.
Data binding
Flex data binding allows you to assign the value of the lastResult attribute of a CallResponder to a user interface
component. When the last result updates, Flex automatically updates the component.
Flex uses curly braces {} to bind data to an attribute of a component. In this example, Flex binds the lastResult value
to the text attribute of the Label component.
Examine the data binding for the Label component:
<s:Label x="70" y="60"
text="{getLocalizedMessageResult.lastResult}"
fontWeight="bold" fontSize="24" fontStyle="italic"
color="red" id="richEditableText"
creationComplete="label_creationCompleteHandler(event)"/>
Use this file to import the entire database into your MySQL installation. It creates the fb_tutorial_db
database, which contains three tables. The tables in the database are departments, employees, and dept_emp.
• fb_tutorial_db_tables.sql
Use this file to import just the three tables into an existing database. This file is provided in case you do not have
privileges to create a database in your MySQL installation. See the ReadMe file for information on importing
this file.
You can install the database either from the command line or using the phpMyAdmin utility for MySQL databases.
2 (Command Line) Execute the following command from a terminal window for your operating system.
<MySQL_Install_Dir>/bin/mysql -u root -p < fb_tutorial_db_full.sql
3 (phpMyAdmin) From the phpMyAdmin home page, navigate to the Import page. Browse to the downloaded SQL
file and import the database.
4 (ColdFusion) In the ColdFusion Administrator, add fb_tutorial_db as a data source.
The following table lists the settings for the data source using the default configuration for ColdFusion 8:
Database fb_tutorial_db
Server 127.0.0.1
Port 3306
<!---
This sample service contains functions that illustrate typical service operations.
This code is for prototyping only.
Authenticate the user prior to allowing them to call these methods. You can find more
information at http://www.adobe.com/go/cf9_usersecurity
--->
<cffunction name="getBooks" output="false" access="remote" returntype="any" >
<!--- Retrieve set of records and return them as a query or array. --->
<!--- Add authorization or any logical checks for secure access to your data --->
<cfset var qAllBooks="">
<cfquery name="qAllBooks" datasource="cfbookclub">
SELECT * FROM Books
</cfquery>
<cfreturn qAllBooks>
</cffunction>
http://localhost:8500/books/bookservicetest.cfm
You can also test a service after importing the service into Flash Builder. Use Test Operation, which is available from
the Data/Service view.
Flex, however, separates client code from server code. The remote service returns only data. Flex binds the returned
data to user interface components in the client application.
1 In Flash Builder, select New > Flex Project to create a ColdFusion server project. Name the project Books.
Set the Application Server Type to ColdFusion. Enable Use Remote Object Access Service and select ColdFusion
Flash Remoting.
Flash Builder provides multiple ways to connect to a data service. In this scenario, you first create the user
interface. Then from a user interface component, you connect to a service and specify the remote operation.
8 Click Browse and navigate to the BookService.cfc you created previously. Click Finish.
Provide authorization credentials as needed for your system.
The Data Services View now displays the BookService.
9 Again, from the context menu for the DataGrid, select Bind to Data.
The Bind to Data dialog now opens with New Service Call selected.
BookService is the only service available in the Flex project.
getBooks() is the only operation available in the service.
10 In the Bind to Data dialog, select Configure Return Type to define the data type for returned data.
Flex uses the return data type to access service operations. The BookService service does not define the data type
for returned data. Flash Builder uses client-side typing to define a custom data type for the returned data.
Some services, such as those provided by LiveCycle Data Services, provide server-side typing. With server-side
typing, Flash Builder does not have to configure the data type for returned data.
11 In the Configure Return Type dialog, Auto-Detect the Return Type is selected by default. Click Next.
Flash Builder introspects the service to determine the data and data types returned.
12 Specify Book in the Array Of field to define a custom type for returned data.
The BookService returns an array of records from the data service. Each record is a complex data type representing
a database record for a book. The custom type Book provides access to each field of the record.
The Configure Return Type dialog displays the properties of the data type returned by the service. Click Finish.
When Flash Builder configures a return type, it accesses the database to create a value object. The properties of
the custom data type are derived from the value object. You can view the properties of the data type before
proceeding.
13 In the Bind to Data dialog, click OK.
Flash Builder binds the data returned from the service call to the DataGrid component. It modifies the columns of
the DataGrid, binding the value returned for each Book property to a column in the DataGrid.
14 Make sure the DataGrid is still selected. In the Properties view, click Configure Columns and then do the following
steps:
a Select the ISSPOTLIGHT column. Click Delete to delete the column.
b Delete all columns except TITLE and GENRE.
c Select the TITLE column. Edit the Header Text field to rename the column Title.
d Rename the GENRE column to Genre.
e With the GENRE column selected, click Up to rearrange the order of the columns.
f Click OK.
15 In Design View, grab the far left handle of the DataGrid and resize it to a more normal shape. Save and run the
application.
<?php
/**
* This sample service contains functions that illustrate typical service operations.
* This code is for prototyping only.
*
* Authenticate users before allowing them to call these methods.
*/
/**
* The constructor initializes the connection to database. Everytime a request is
* received by Zend AMF, an instance of the service class is created and then the
* requested method is called.
*/
class EmployeeService {
var $username = "USERNAME";
var $password = "PASSWORD";
var $server = "localhost";
var $port = "3306";
var $databasename = "fb_tutorial_db";
var $tablename = "employees";
var $connection;
public function __construct() {
$this->connection = mysqli_connect(
$this->server,
$this->username,
$this->password,
$this->databasename,
$this->port
);
$this->throwExceptionOnError($this->connection);
}
public function getEmployees() {
mysqli_stmt_execute($stmt);
$this->throwExceptionOnError();
$rows = array();
while (mysqli_stmt_fetch($stmt)) {
$rows[] = $row;
$row = new stdClass();
mysqli_stmt_bind_result($stmt, $row->emp_no, $row->birth_date,
$row->first_name, $row->last_name, $row->gender, $row->hire_date);
}
mysqli_stmt_free_result($stmt);
mysqli_close($this->connection);
return $rows;
}
/**
* Utitity function to throw an exception if an error occurs
* while running a mysql command.
*/
private function throwExceptionOnError($link = null) {
if($link == null) {
$link = $this->connection;
}
if(mysqli_error($link)) {
$msg = mysqli_errno($link) . ": " . mysqli_error($link);
throw new Exception('MySQL Error - '. $msg);
}
}
}
?>
This PHP class contains functions that implement data service operations. Flash Builder introspects the service
operations in the PHP class to create ActionScript classes in the client application. The client application accesses
the data service using these ActionScript classes.
3 Save EmployeeService.php at the following location:
<Web Root>/PHPService/services/EmployeeService.php
Note: Make sure that the filename corresponds to the name of the class implementing the PHP service.
4 In EmployeeService.php, examine the code that calls the database.
• Connecting to data:
The code uses global variables and a constructor function that connects to the database server.
Substitute your connection settings for the global variables.
• Call the database:
$stmt = mysqli_prepare($this->connection, "SELECT * FROM $this->tablename");
mysqli_stmt_execute($stmt);
This code implements a basic PHP call to a database to return a result set. This call uses prepared statements
available with the MySQLi extension. Prepares statements provide more security than a basic database query.
• Return the data as an array of rows:
$rows = array();
mysqli_stmt_bind_result($stmt, $row->emp_no, $row->birth_date,
$row->first_name, $row->last_name, $row->gender, $row->hire_date);
while (mysqli_stmt_fetch($stmt)) {
$rows[] = $row;
$row = new stdClass();
mysqli_stmt_bind_result($stmt, $row->emp_no, $row->birth_date,
$row->first_name, $row->last_name, $row->gender, $row->hire_date);
}
return $rows;
Flex expects data returned by the operation to be an object or an array of objects. The PHP code that handles
the returned result set iterates through the result, returning an array of objects. Each object in the array
corresponds to a retrieved record from the database, containing values for each column in the record.
The code uses bound results for the prepared statement. This call allows the values of the result to correctly be
bound to expected values of the data.
• Exception handling
The code creates a utility function to catch exceptions.
2 Save tester.php in the same folder as EmployeeService.php, and call the service from a web browser.
If the call is successful, tester dumps records from the database:
array(999) {
[0]=>
object(stdClass)#4 (6) {
["emp_no"]=>
string(5) "10002"
["birth_date"]=>
string(10) "1964-06-02"
["first_name"]=>
string(7) "Bezalel"
["last_name"]=>
string(6) "Simmel"
["gender"]=>
string(1) "F"
["hire_date"]=>
string(10) "1985-11-21"
}
[1]=>
object(stdClass)#5 (6) {
["emp_no"]=>
string(5) "10003"
["birth_date"]=>
string(10) "1959-12-03"
["first_name"]=>
string(5) "Parto"
["last_name"]=>
string(7) "Bamford"
["gender"]=>
string(1) "M"
["hire_date"]=>
string(10) "1986-08-28"
}
[2]=>
object(stdClass)#6 (6) {
["emp_no"]=>
. . .
If there is an error in the service, PHP displays information to help locate the error.
Warning: mysqli_connect() [function.mysqli-connect]: (28000/1045):
Access denied for user 'admin'@'localhost' (using password: YES) in
C:\wamp2\www\PHP_Service\services\PHPservice.php on line 6
You can also test a service after importing the service into Flash Builder. Use Test Operation, which is available from
the Data/Service view.
In a traditional relationship, a server template mixes server code with client code. When the client queries a database,
it dynamically embeds HTML code with returned data.
Flex, however, separates client code from server code. The remote service returns only data. Flex binds the returned
data to user interface components in the client application.
1 In Flash Builder, select File > New > Flex Project.
2 Specify PHP_Service for the project name and set the Application Server Type to PHP.
Note: If you forget to set the application server type when you create the project, you can later specify the server type
from the Project Properties page.
3 Click Next. Verify your PHP configuration and click Validate Configuration.
4 For Output Folder, specify the PHPService folder you created previously.
Flash Builder suggests a default location for the output folder. Use the location that already contains
EmployeeService.php. Here is the location previously specified:
<Web Root>/PHPService/
5 Click Finish.
Click Finish. Flash Builder prompts you to install or update the Zend Framework, if necessary.
The Data Services View now displays the EmployeeService.
11 From the DataGrid context menu, again select Bind to Data.
The Bind to Data dialog opens with New Service Call selected.
EmployeeService is the only service available in the Flex project.
getEmployeess() is the only operation available in the service.
12 In the Bind to Data dialog, select Configure Return Type to define the data type for returned data.
Flex uses the return data type to access service operations. The EmployeeService service does not define the data
type for returned data. Flash Builder uses client-side typing to define a custom data type for the returned data.
13 In the Configure Return Type dialog, Auto-Detect the Return Type is selected by default. Click Next.
14 Specify Employee for the name of the type.
The EmployeeService returns a complex data type representing a database record for an employee. The custom type
Employee provides access to each field of the record.
View the properties of the Employee data type returned by the service. Click Finish.
When Flash Builder configures a return type, it accesses the database to create a value object. The properties of
the custom data type are derived from the value object. You can view and modify the properties of the data type
before proceeding.
15 In the Bind to Data dialog, click OK.
Flash Builder binds the data returned from the service call to the DataGrid component. It modifies the columns of
the DataGrid, binding the value returned for each Employee property to a column in the DataGrid.
16 Make sure the DataGrid is still selected. In the Properties view, click Configure Columns and then do the following
steps:
a Select the hire_date column. Click Delete to delete the column.
b Similarly, delete all columns except emp_no, first_name, and last_name.
c Select the emp_no column. Click Up to move it to the first position.
d In the Header Text field, rename the emp_no column to ID.
e Similarly, rename the first_name and last_name columns.
f Click OK.
17 With the DataGrid still selected, in the Properties view, specify False for the editable property.
18 Select File > Save to save the application file. Then select Run > Run PHP_Service to run the application.
• count()
Data grid
<cfcomponent output="false">
<!---
This sample service contains functions that illustrate typical service operations.
This code is for prototyping only.
Authenticate the user prior to allowing them to call these methods. You can find more
information at http://www.adobe.com/go/cf9_usersecurity
--->
<cffunction name="getItems_paged" output="false" access="remote" returntype="any" >
<cfargument name="startIndex" type="numeric" required="true" />
<cfargument name="numItems" type="numeric" required="true" />
<!--- The LIMIT keyword is valid for MySQL database only, modify according to your database
--->
<cfset var qRead="">
<cfquery name="qRead" datasource="fb_tutorial_db">
SELECT * FROM employees LIMIT #startIndex#, #numItems#
</cfquery>
<cfreturn qRead>
</cffunction>
<cfreturn qread.empCount>
</cffunction>
</cfcomponent>
3 In Flash Builder, create a Flex project. Name the project PagingCF and specify ColdFusion for the server technology
as listed below. Click Next.
• Application Server Type: ColdFusion
• Enable Use Remote Object Access Service
• Select ColdFusion Flash Remoting
4 Validate your ColdFusion settings and specify the PagingCF directory for the Output Folder. Click Finish.
5 From the Flash Builder Data menu, select Connect to Data Service. Select ColdFusion and click Next.
6 Click Browse and navigate to the PagingService.cfc file you created in step 2. Click Finish.
7 In the Flash Builder Data/Services view, from the context menu for the getItems_paged() operation, select
Configure Return Type.
8 In the Configure Return Type dialog, Auto-Detect the Return Type is selected by default. Click Next.
9 Specify values and types for the parameters to the getItems_paged() operation as described below. Click Next:
startIndex Number 0
numItems Number 10
10 Specify Employee in the Array Of field toto define a custom type for returned data.
Flex uses custom data types to access and update complex data types returned from a server.
The Configure Return Type dialog displays the properties of the data type returned by the service.
11 Click Finish to configure the Employee return type.
12 In the Data/Services view, from the context menu for the getItems_paged() operation, select Enable Paging.
13 In the Select Unique Identifier dialog, select emp_no and click Next.
14 In the Confirm Paging dialog, leave the Page Size field blank. Specify the count() operation from the drop-down
list. Click Finish.
Note: By default, Flash Builder configures the page size to be 20 records. This dialog allows you to specify a custom
page size for an operation.
Bind To Data
2 In your favorite PHP editor, create the following PHP file that implements the required paging functions. Name
the file PagingService.php and save it in the services directory.
<?php
/**
* This sample service contains functions that illustrate typical service operations.
* This code is for prototyping only.
*
* Authenticate users before allowing them to call these methods.
*/
class PagingService {
/* connection variables */
var $username = "USERNAME";
var $password = "PASSWORD";
var $server = "localhost";
var $port = "3306";
var $databasename = "fb_tutorial_db";
var $tablename = "employees";
var $connection;
$this->throwExceptionOnError($this->connection);
}
mysqli_stmt_execute($stmt);
$this->throwExceptionOnError();
mysqli_stmt_bind_result($stmt, $rec_count);
$this->throwExceptionOnError();
mysqli_stmt_fetch($stmt);
$this->throwExceptionOnError();
mysqli_stmt_free_result($stmt);
mysqli_close($this->connection);
return $rec_count;
}
$stmt = mysqli_prepare($this->connection,
"SELECT * FROM $this->tablename LIMIT ?, ?");
$this->throwExceptionOnError();
$rows = array();
while (mysqli_stmt_fetch($stmt)) {
$rows[] = $row;
$row = new stdClass();
mysqli_stmt_bind_result($stmt, $row->emp_no, $row->birth_date,
$row->first_name, $row->last_name,
$row->gender, $row->hire_date);
}
mysqli_stmt_free_result($stmt);
mysqli_close($this->connection);
return $rows;
}
/**
* Utitity function to throw an exception if an error occurs
* while running a mysql command.
*/
private function throwExceptionOnError($link = null) {
if($link == null) {
$link = $this->connection;
}
if(mysqli_error($link)) {
$msg = mysqli_errno($link) . ": " . mysqli_error($link);
throw new Exception('MySQL Error - '. $msg);
}
}
}
?>
3 In PagingService.php, modify the connection variables to provide your server, username, and password for
access to the fb_tutorial_db database.
4 In Flash Builder, create a Flex project. Name the project PagingPHP and specify PHP for the server technology.
Click Next.
5 Specify the Web Root and Root URL for your system. Validate your server settings and specify the PagingPHP
directory for the Output Folder. Click Finish.
6 From the Flash Builder Data menu, select Connect to Data Service. Select PHP and click Next.
7 Click Browse and navigate to the PagingService.php file you created in step 1. Click Finish.
If the Zend Framework, which includes Zend AMF, is not installed on your system, click OK to install the Zend
Framework.
8 In the Flash Builder Data/Services view, from the context menu for the getItems_paged() operation, select
Configure Return Type.
9 In the Configure Return Type dialog, Auto-Detect the Return Type is selected by default. Click Next.
10 Specify values and types for the parameters to the getItems_paged() operation as described below. Click Next:
startIndex int 0
numItems int 20
11 Specify Employee in the Array Of field to define a custom type for returned data.
Flex uses custom data types to access and update complex data types returned from a server.
The Configure Return Type dialog displays the properties of the data type returned by the service.
12 Click Finish to configure the Employee return type.
13 In the Data/Services view, from the context menu for the getItems_paged() operation, select Enable Paging.
14 In the Select Unique Identifier dialog, select emp_no and click Next.
15 In the Confirm Paging dialog, leave the Page Size field blank. Specify the count() operation from the drop-down
list. Click Finish.
Note: By default, Flash Builder configures the page size to be 20 records. This dialog allows you to specify a custom
page size for an operation.
5 In the Bind to Data operation, select New Service Call. For the PagingService, select the get Items Paged()
operation from the drop-down list,. Click OK.
• deleteItem(itemID:Number):void
• updateItem((item: CustomDatatype):void
• getItem(itemID:Number): CustomDatatype
CustomDatatype is a data type representing complex data returned from the server. In server-side typing, the service
defines the custom data type. In client-side typing, use Flash Builder to introspect the service and configure the custom
data type.
Note: The required data management operation signatures listed in this tutorial are a subset of the signatures that can
be used. For a complete list of the operation signatures you can use, see Enabling data management.
You can implement the service in this tutorial using client-side or server-side typing. The service is defined in
EmployeeService.cfc. If you use server-side typing, you define the Employee data type in a separate
Employee.cfc.
The server code in EmployeeService.cfc is basically the same in both versions. However, in the version that
implements server-side typing, the functions access the Employee data type defined in Employee.cfc.
• “Create the remote service and import it into a Flex project (client-side typing)” on page 46
• “Create the remote service and import it into a Flex project (server-side typing)” on page 49
Create the remote service and import it into a Flex project (client-side typing)
1 In your web root create a folder named DataMgtCF.
2 In your favorite ColdFusion editor, create the following CFC. Name the CFC EmployeeService.cfc and place it
in the DataMgtCF folder in your web root.
EmployeeService.cfc contains the functions required by Flash Builder to implement data management.
<!---
This sample service contains functions that illustrate typical service operations.
This code is for prototyping only.
Authenticate the user prior to allowing them to call these methods. You can find more
information at http://www.adobe.com/go/cf9_usersecurity
--->
<cfcomponent output="false">
<cffunction name="getAllItems" output="false" access="remote" returntype="any" >
<cfset var qAllItems="">
<cfquery name="qAllItems" datasource="fb_tutorial_db">
SELECT * FROM employees
</cfquery>
<cfreturn qAllItems>
</cffunction>
<cfreturn qItem>
</cffunction>
<cfreturn result.GENERATED_KEY/>
</cffunction>
</cfcomponent>
3 In Flash Builder, create a Flex project. Name the project DataMgtCF. Specify ColdFusion for the server technology
as listed below. Click Next.
• Application Server Type: ColdFusion
• Enable Use Remote Object Access Service
• Select ColdFusion Flash Remoting
4 Validate your ColdFusion settings and specify the DataMgtCF folder for the Output Folder. Click Finish.
5 From the Flash Builder Data menu, select Connect to Data/Service. Select ColdFusion. Click Next.
6 Click Browse and navigate to the EmployeeService.cfc file you created in step 2. Click Finish.
Provide authorization credentials as needed for your system.
7 In the Flash Builder Data/Services view, from the context menu for the getItem() operation, select Configure
Return Type.
Flash Builder requires a custom data type for data returned from the data service. By introspecting the getItem()
operation, you can define the custom data type Employee.
8 In the Configure Return Type dialog, Auto-Detect the Return Type is selected by default. Click Next.
9 Specify a value and type for the parameter to the getItem() operation as described below. Click Next:
For getItem(), you supply a valid parameter corresponding to the key field for the database. Number and 10001
are valid type and value for itemID
10 Specify Employee in the Array Of field to define a custom type for returned data.
Flex uses custom data types to access and update complex data types returned from a server. getItem() returns
the fields of a record from the Employees table in the database
The Configure Return Type dialog displays the properties of the data type returned by the service.
Create the remote service and import it into a Flex project (server-side typing)
1 In your web root create a folder named DataMgtCF.
2 In your favorite ColdFusion editor, create the following CFC. Name the CFC Employee.cfc and place it in the
DataMgtCF folder.
Employee.cfc defines the Employee data type that is returned by the service.
<cfcomponent>
<cfproperty name="emp_id" type="numeric">
<cfproperty name="bdate" type="date">
<cfproperty name="fname" type="string">
<cfproperty name="lname" type="string">
<cfproperty name="gender" type="string">
<cfproperty name="hdate" type="date">
</cfcomponent>
3 Now create EmployeeService.cfc and place it in the DataMgtCF folder alongside Employee.cfc.
EmployeeService.cfc contains the functions required by Flash Builder to implement data management.
<!---
This sample service contains functions that illustrate typical service operations.
This code is for prototyping only.
Authenticate the user prior to allowing them to call these methods. You can find more
information at http://www.adobe.com/go/cf9_usersecurity
--->
<cfcomponent output="false">
<cffunction name="getAllEmployees" output="false" access="remote"
returntype="Employee[]" >
<cfset var returnarray = ArrayNew(1)>
<cfset var temp = "">
<cfset var qAllEmployees="">
<cfquery name="qAllEmployees" datasource="fb_tutorial_db">
SELECT * FROM employees
</cfquery>
<cfloop query="qAllEmployees">
<cfobject component="Employee" name="tempname">
<cfset tempname.emp_id = #qAllEmployees.emp_no#>
<cfset tempname.fname = #qAllEmployees.first_name#>
<cfset tempname.lname = #qAllEmployees.last_name#>
<cfset tempname.gender = #qAllEmployees.gender#>
<cfset tempname.bdate = #qAllEmployees.birth_date#>
<cfset tempname.hdate = #qAllEmployees.hire_date#>
<cfset temp = ArrayAppend(returnarray, tempname)>
</cfloop>
<cfreturn returnarray>
</cffunction>
<cfreturn qItem>
</cffunction>
<cfreturn result.GENERATED_KEY/>
</cffunction>
<cffunction name="updateEmployee" output="false" access="remote" returntype="void" >
<cfargument name="item" type="Employee" required="true" />
</cfcomponent>
4 In Flash Builder, create a Flex project. Name the project DataMgtCF. Specify ColdFusion for the server technology
as listed below. Click Next.
• Application Server Type: ColdFusion
• Enable Use Remote Object Access Service
• Select ColdFusion Flash Remoting
5 Validate your ColdFusion settings and specify the DataMgtCF folder for the Output Folder. Click Finish.
6 From the Flash Builder Data menu, select Connect to Data/Service. Select ColdFusion. Click Next.
7 Click Browse and navigate to the EmployeeService.cfc file you created in step 2. Click Finish.
Provide authorization credentials as needed for your system.
Next:“Enable Data Management Features” on page 51
3 In the Select Unique Identifier dialog, select emp_id and click Next.
4 In the Map Database Operations dialog, specify the following operations. Click Finish.
• Create (Add) Operation: createEmployee( )
Data management is now enabled for this operation. Flash Builder generates client code that can update data using
a combination of the mapped operations.
Next:“Create the application and add a DataGrid and Buttons” on page 52
Property Value
ID dg
Editable true
4 Drag four Buttons to the Design Area, lining them up beneath the DataGrid.
5 Double-click each button to edit their labels. Provide the following Labels:
Label
Add
Label
Delete
Revert
6 In the Data/Services view, select the getAllEmployees() operation and drop it onto the DataGrid.
In the Bind to Data dialog, EmployeeService and getAllEmployees() are selected. Click OK.
7 (Optional) With the DataGrid selected, in the Properties view Click Configure Columns and do the following:
Rename and rearrange the columns.
Next:“Generate event handlers for the Buttons” on page 53
e.first_name = "New";
e.last_name = "New";
e.birth_date = birthDate;
e.hire_date = hireDate;
e.gender = "M";
dg.dataProvider.addItem(e);
dg.verticalScrollPosition = dg.dataProvider.length -1;
Server-side typing:
var e:Employee = new Employee();
var birthDate:Date = new Date(2000, 01, 01);
var hireDate:Date = new Date(2000, 01, 01);
e.fname = "New";
e.lname = "New";
e.bdate = birthDate;
e.hdate = hireDate;
e.gender = "M";
dg.dataProvider.addItem(e);
dg.verticalScrollPosition = dg.dataProvider.length -1;
3 In the Script block, add the following import statement after the existing import statements:
import services.employeeservice.EmployeeService;
import valueObjects.Employee;
4 In Design mode, add an On Click event handler for the Delete button.
The data types differ slight for the client-side and server-side implementations. Make sure to use the correct code
for the event handler.
Client-side typing:
employeeService.deleteEmployee(dg.selectedItem.emp_no);
Server-side typing:
employeeService.deleteEmployee(dg.selectedItem.emp_id);
5 Similarly, add an On Click event handler for the Revert button with the following code:
employeeService.getDataManager(employeeService.DATA_MANAGER_EMPLOYEE).revertChanges();
getAllEmployeesResult.token = employeeService.getAllEmployees();
6 Add an On click event handler for the Save All Changes button with the following code:
employeeService.commit();
7 For the creationCompleteHandler() for the DataGrid, add the following lines of code:
protected function dg_creationCompleteHandler(event:FlexEvent):void
{
employeeService.getDataManager(employeeService.DATA_MANAGER_EMPLOYEE).autoCommit=false;
employeeService.getDataManager(employeeService.DATA_MANAGER_EMPLOYEE).deleteItemOnRemoveFro
mFill=true;
getAllItemsResult.token = employeeService.getAllItems();
}
This code makes sure that deleted items can be reverted by selecting the Revert button.
8 Save the application and select Run > Run DataMgtCF.
You can update employees in place in the DataGrid. When you click Save All Changes, the changes are updated on
the server. The server is updated is because the data management feature calls the updateItem() operation to keep
the data synchronized between the client and the server.
Click the Revert button to undo any changes you made before you click Save All Changes.
You can add and delete employees. When you add and delete employees, the data management features take care
of adding or removing the DataGrid rows. Without data management enabled, you code the updates to the
DataGrid yourself.
When you add an employee, the Employee Number defaults to zero. This default value is because the new employee
has not been updated on the server. When you click Save All Changes, the new employee is added to the server. At
that time, an Employee Number is generated.
Click the Save All Changes button to write all changes to the database.
In this tutorial, you create an application that contains an editable DataGrid that displays employee records. You can
modify one or more records in place in the DataGrid. You can also add or delete selected records. All changes in the
DataGrid are local until you select a Save All Changes button that updates the database.
You can implement the service in this tutorial using client-side or server-side typing. The service is defined in
EmployeeService.php. If you use server-side typing, you define the Employee data type in a separate Employee class
defined in EmployeeService.php.
The server code in EmployeeService.php is basically the same in both versions. However, in the version that
implements server-side typing, the functions access the Employee data type defined in the Employee class.
• “Create the remote service and import it into a Flex project (client-side typing)” on page 56
• “Create the remote service and import it into a Flex project (server-side typing)” on page 60
Create the remote service and import it into a Flex project (client-side typing)
1 In your web root, create a folder named DataMgtPHP. Within that folder, create a folder named services.
2 In your favorite PHP editor, create the following PHP file, which implements a service. Name the file
EmployeeService.php and place it in the DataMgtPHP/services folder in your web root.
<?php
class EmployeeService {
var $connection;
$this->throwExceptionOnError($this->connection);
}
mysqli_stmt_execute($stmt);
$this->throwExceptionOnError();
$rows = array();
while (mysqli_stmt_fetch($stmt)) {
$rows[] = $row;
$row = new stdClass();
mysqli_stmt_bind_result($stmt, $row->emp_no, $row->birth_date,
$row->first_name, $row->last_name, $row->gender, $row->hire_date);
}
mysqli_stmt_free_result($stmt);
mysqli_close($this->connection);
return $rows;
}
$stmt = mysqli_prepare($this->connection,
"SELECT * FROM $this->tablename where emp_no=?");
$this->throwExceptionOnError();
mysqli_stmt_execute($stmt);
$this->throwExceptionOnError();
if(mysqli_stmt_fetch($stmt)) {
return $row;
} else {
return null;
}
}
$stmt = mysqli_prepare($this->connection,
"INSERT INTO $this->tablename (birth_date,
first_name, last_name, gender, hire_date) VALUES (?, ?, ?, ?, ?)");
$this->throwExceptionOnError();
mysqli_stmt_execute($stmt);
$this->throwExceptionOnError();
$autoid = mysqli_stmt_insert_id($stmt);
mysqli_stmt_free_result($stmt);
mysqli_close($this->connection);
return $autoid;
}
$stmt = mysqli_prepare($this->connection,
"UPDATE $this->tablename SET emp_no=?, birth_date=?,
first_name=?, last_name=?, gender=?, hire_date=?
WHERE emp_no=?");
$this->throwExceptionOnError();
mysqli_stmt_execute($stmt);
$this->throwExceptionOnError();
mysqli_stmt_free_result($stmt);
mysqli_close($this->connection);
}
$stmt = mysqli_prepare($this->connection,
"DELETE FROM $this->tablename WHERE emp_no = ?");
$this->throwExceptionOnError();
mysqli_stmt_free_result($stmt);
mysqli_close($this->connection);
}
/**
* Utitity function to throw an exception if an error occurs
* while running a mysql command.
*/
private function throwExceptionOnError($link = null) {
if($link == null) {
$link = $this->connection;
}
if(mysqli_error($link)) {
$msg = mysqli_errno($link) . ": " . mysqli_error($link);
throw new Exception('MySQL Error - '. $msg);
}
}
}
?>
3 Modify the connection variables to provide your server, user name, and password for access to the
fb_tutorial_db database.
4 In Flash Builder, create a Flex project. Name the project DataMgtPHP and specify PHP for the server technology.
Click Next.
5 Specify the Web Root and Root URL for your system. Validate your server settings. Specify the DataMgtPHP
directory for the Output Folder. Click Finish.
6 From the Flash Builder Data menu, select Connect to Data Service. Select PHP. Click Next.
7 Click Browse and navigate to the EmployeeService.php file you created in step 2. Select EmployeeService.php.
Click Finish.
8 In the Flash Builder Data/Services view, from the context menu for the getEmployeesbyID() operation, select
Configure Return Type.
Flash Builder requires a custom data type for data returned from the data service. By introspecting the
getEmployeesbyID() operation, you can define the custom data type Employee.
9 In the Configure Return Type dialog, Auto-Detect the Return Type is selected by default. Click Next.
10 Specify a value and type for the parameter to the getEmployeesByID() operation as described below. Click Next:
For getEmployeesByID(), you supply a valid parameter corresponding to the key field for the database. int and
10001 are valid type and value for itemID.
11 Specify Employee to define a custom type for returned data.
Flex uses custom data types to access and update complex data types returned from a server. getEmployeesByID()
returns the fields of a record from the Employees table in the database
The Configure Return Type dialog displays the properties of the data type returned by the service.
12 Click Finish to configure Employee as the return type.
13 In the Flash Builder Data/Services view, from the context menu for the getAllEmployees() operation, select
Configure Return Type.
14 In the Configure Return Type dialog, Auto-Detect the Return Type is selected by default. Click Next.
15 Select Use an Existing Data Type. Select Employee from the Array Of drop-down list. Click Finish.
16 Configure the parameter type and return type for deleteEmployees() as follows:
a From the context menu for the deleteEmployees() operation, select Configure Input Types. Specify int for the
type. Click OK.
b From the context menu for the deleteEmployees() operation, select Configure Return Type. Select Use An
Existing Type. Specify void. Click Finish.
Next:“Enable Data Management Features” on page 64
Create the remote service and import it into a Flex project (server-side typing)
This release of Flash Builder uses PHP DocBlock comments to recognize server-side data type. The sample service in
this example shows how to use DocBlock comments to define a custom data type. The example also shows how to
specify a data type for function arguments and return values.
1 In your web root, create a folder named DataMgtPHP. Within that folder, create a folder named services.
2 In your favorite PHP editor, create the following PHP file, which implements a service. The service also contains
an Employee class that defines the Employee data type.
Name the file EmployeeService.php and place it in the DataMgtPHP/services folder in your web root.
<?php
class Employee {
/**
* @var int
*/
var $emp_id;
/**
* @var string
*/
var $bdate;
/**
* @var string
*/
var $fname;
/**
* @var string
*/
var $lname;
/**
* @var string
*/
var $gender;
/**
* @var string
*/
var $hdate;
}
class EmployeeService {
var $connection;
$this->throwExceptionOnError($this->connection);
}
/**
mysqli_stmt_execute($stmt);
$this->throwExceptionOnError();
$rows = array();
while (mysqli_stmt_fetch($stmt)) {
$rows[] = $row;
$row = new stdClass();
mysqli_stmt_bind_result($stmt, $row->emp_id, $row->bdate,
$row->fname, $row->lname, $row->gender, $row->hdate);
}
mysqli_stmt_free_result($stmt);
mysqli_close($this->connection);
return $rows;
}
/**
* @param int $itemID
* @return Employee
*/
public function getEmployeesByID($itemID) {
$stmt = mysqli_prepare($this->connection,
"SELECT * FROM $this->tablename where emp_no=?");
$this->throwExceptionOnError();
mysqli_stmt_execute($stmt);
$this->throwExceptionOnError();
mysqli_stmt_bind_result($stmt, $item->emp_no, $item->bdate,
$item->fname, $item->lname, $item->gender, $item->hdate);
if(mysqli_stmt_fetch($stmt)) {
return $item;
} else {
return null;
}
}
/**
* @param Employee $item
* @return int
*/
public function createEmployees($item) {
$stmt = mysqli_prepare($this->connection,
"INSERT INTO $this->tablename (birth_date,
first_name, last_name, gender, hire_date) VALUES (?, ?, ?, ?, ?)");
$this->throwExceptionOnError();
mysqli_stmt_execute($stmt);
$this->throwExceptionOnError();
$autoid = mysqli_stmt_insert_id($stmt);
mysqli_stmt_free_result($stmt);
mysqli_close($this->connection);
return $autoid;
}
/**
* @param Employee $item
*/
public function updateEmployees($item) {
$stmt = mysqli_prepare($this->connection,
"UPDATE $this->tablename SET emp_no=?, birth_date=?,
first_name=?, last_name=?, gender=?, hire_date=?
WHERE emp_no=?");
$this->throwExceptionOnError();
mysqli_stmt_execute($stmt);
$this->throwExceptionOnError();
mysqli_stmt_free_result($stmt);
mysqli_close($this->connection);
}
/**
* @param int $itemID
*/
public function deleteEmployees($itemID) {
$stmt = mysqli_prepare($this->connection,
"DELETE FROM $this->tablename WHERE emp_no = ?");
$this->throwExceptionOnError();
mysqli_stmt_free_result($stmt);
mysqli_close($this->connection);
}
/**
* Utitity function to throw an exception if an error occurs
* while running a mysql command.
*/
private function throwExceptionOnError($link = null) {
if($link == null) {
$link = $this->connection;
}
if(mysqli_error($link)) {
$msg = mysqli_errno($link) . ": " . mysqli_error($link);
throw new Exception('MySQL Error - '. $msg);
}
}
}
3 Modify the connection variables to provide your server, user name, and password for access to the
fb_tutorial_db database.
4 In Flash Builder, create a Flex project. Name the project DataMgtPHP and specify PHP for the server technology.
Click Next.
5 Specify the Web Root and Root URL for your system. Validate your server settings. Specify the DataMgtPHP
directory for the Output Folder. Click Finish.
6 From the Flash Builder Data menu, select Connect to Data Service. Select PHP. Click Next.
7 Click Browse and navigate to the EmployeeService.php file you created in step 2. Select EmployeeService.php.
Click Finish.
Next:“Enable Data Management Features” on page 64
2 From the context menu for the Employee data type, select Enable Data Management.
Click Finish. Data management is now enabled for this operation. Flash Builder generates client code that can
update data using a combination of the mapped operations.
Next:“Create the application and add a DataGrid and Buttons” on page 66
Property Value
ID dg
Editable true
4 Drag four Buttons to the Design Area, lining them up beneath the DataGrid.
5 Double-click each button to edit their labels. Provide the following Labels:
Label
Add
Delete
Revert
6 In the Data/Services view, select the getAllEmployees() operation and drop it onto the DataGrid.
In the Bind to Data dialog, EmployeeService and getAllEmployees() are selected. Click OK.
7 (Optional) With the DataGrid selected, in the Properties view click Configure Columns. Rename and rearrange the
columns.
Next:“Generate and code event handlers for the Buttons” on page 67
Server-side typing:
var e:Employee = new Employee();
e.fname = "New";
e.lname = "New";
e.bdate = "2000-01-01";
e.hdate = "2000-01-01";
e.gender = "M";
dg.dataProvider.addItem(e);
dg.verticalScrollPosition = dg.dataProvider.length -1;
3 In the Script block, add the following import statements after the existing import statements:
import services.employeeservice.EmployeeService;
import valueObjects.Employee;
4 In Design mode, add an On Click event handler for the Delete button.
The data types differ slightly for the client-side and server-side implementations. Make sure to use the correct code
for the event handler.
Client-side typing:
employeeService.deleteEmployees(dg.selectedItem.emp_no);
Server-side typing:
employeeService.deleteEmployees(dg.selectedItem.emp_id);
5 Similarly, add an On Click event handler for the Revert button with the following code:
employeeService.getDataManager(employeeService.DATA_MANAGER_EMPLOYEE).revertChanges();
getAllEmployeesResult.token = employeeService.getAllEmployees();
6 Add an On click event handler for the Save All Changes button with the following code:
employeeService.commit();
7 For the creationCompleteHandler() for the DataGrid, add the following lines of code:
employeeService.getDataManager(employeeService.DATA_MANAGER_EMPLOYEE).deleteItemOnRemoveFro
mFill=true;
getAllItemsResult.token = employeeService.getAllEmployees();
}
This code makes sure that deleted items can be reverted by selecting the Revert button.
8 Save the application and select Run > Run DataMgtPHP.
You can update employees in place in the DataGrid. When you click Save All Changes, the changes are updated on
the server. The server is updated because the data management feature calls the updateEmployees() operation to
keep the data synchronized between the client and the server.
Click the Revert button to undo any changes you made before you click Save All Changes.
You can add and delete employees. When you add and delete employees, the data management features take care
of adding or removing the DataGrid rows. Without data management enabled, you code the updates to the
DataGrid yourself.
When you add an employee, the Employee Number defaults to zero. This default value is because the new employee
has not been updated on the server. When you click Save All Changes, the new employee is added to the server. At
that time, an Employee Number is generated.
Click the Save All Changes button to write all changes to the database.