Using AMFPHP (Open Source Flash Development) Part 5

Using Flex to update the product database

In this section, we will show how to create a Flex interface that consumes the ProductService.php file you created earlier. Let’s start by creating a new MXML application by right-clicking the product folder and selecting New > MXML Application. Name the new file productUpdate, as shown in the following screenshot.

tmp9d3-12

Right-click productUpdate in the Navigator panel, and select Set as Default Application. This tells Flex Builder to run this new file when you click the Run button in Flex Builder. To run the HelloWorld example again, you will need to change the default application back to product.mxml.

The following is the complete productUpdate.mxml file to populate a DataGrid with the getProducts remote method and update, remove, and add new products to the database. Copy the code into your productUpdate.mxml file, or copy and paste it from the topic download file. Then scan through the code; after the code, I will walk you through the logic behind the functionality:

tmp9d3-13


 

 

 

tmp9d3-14

 

 

 

tmp9d3-15

 

 

tmp9d3-16

Running the productUpdate.mxml file will launch the new Flex interface that resembles what you created in Flash. Flex is designed for this type of application and layout, so it is considerably easier to get a professional-looking interface. Run the application by clicking the green run button. Once the application is running, click the Get Products button to populate the DataGrid with the data from the getProducts remote method in ProductService.php. Selectone of the products in the DataGrid, and it will populate the TextInputs to the right side of the interface, as shown in the following screenshot.

tmp9d3-17

All of the buttons under the Product Update form are functional, so feel free to update some of the data, create a new product based on an existing product, or delete one of the products you created.

Let’s walk through the MXML code together to understand what type of functionality you have added in order to make this application run properly. Let’s start with the RemoteObject tag at the top of the application. Unlike the RemoteObject tag in the HelloWorld example, this code set has several method declarations. Each of the declarations is necessary so you can set a result-handler function for when the method is called.

The next tag is the DataGrid tag. In this example I have chosen to display only the name, category, price, and quantity fields from the result set. This cleans up the interface a little, and I have also given the columns easily readable header text labels. It is important that you notice the names of the dataField values for each column. These names have to match the DataProvider that we are going to apply to the DataGrid. The current values are the column names in the database.

The <![CDATA[ tag breaks out of MXML and allows for ActionScript inline with the MXML. Starting with the ActionScript area, I have added an import for the alert component. This addition was required in the faultHandler function that now uses the alert component rather than just a simple trace statement.

I am using a meta tag called Bindable on the product object. This meta tag allows me to later bind values to this variable when the variable is changed. You will see that the TextInputs are bound to products and will update when the product variable updates. This is similar to how a DataProvider works on the DataGrid.

The following are the remaining methods in the Script section in order:

■    faultHandler is the specified method by RemoteObject for handling when it cannot connect to the remote service.

■    getProductsHandler is defined by RemoteObject to handle the successful result of the getProducts remote method call. The remote method returns an ArrayCollection, which you set directly against the DataGrid’s DataProvider.

■    refreshProductsHandler is defined by RemoteObject to handle the successful result of updateProduct, removeProduct, and addProduct. This method is similar to the refreshData method that you used in the Flash example. It checks to see whether the Boolean result set is true, which means the operation was successful, and then calls getproducts to sync the Flash interface with the current data on the server.

■    changeHandler is a listener for the DataGrid. When something is selected in the DataGrid, this method is run, and it applies the column that was selected to the product object. Because product is bindable, it then updates the TextInputs if the data in product changes.

■    getParams is the same as it was in the Flash example. This method is called before any update, add, or delete to the database to get the most current data from the TextInputs to be sent to the server.

■    updateProduct is called from the Update button to send the changed data back to the server. This method uses the ID name of the RemoteObject myservice and then can call the remote method directly. removeProduct and addProduct work like this method and are called by their respective buttons.

If you scroll down to the TextInputs, you can see how you use {} to represent a bindable variable. You bind the person to the TextInput text property and the TextArea text property for the description field. These are automatically updated on every mouse click on the DataGrid.

The last piece of the puzzle is the click event on the buttons that explicitly call their corresponding functions to send data back to the server.

After walking through this code, you can see the similarities between the Flash example and the Flex example. You should also have a clear understanding of how RemoteObject works with multiple method calls and different handlers for their specific result sets. In the next, final tutorial section, you will review a simpler way to work with remote data in ActionScript 3.

Class mapping from PHP to ActionScript 3

Class mapping allows a remote PHP object to be mapped directly into an ActionScript object without having to construct code to iterate through the result to populate the class. This can save a lot of time, and it also has the advantage that you can use code completion in the editor because the ActionScript object is defined. Although the concept is technical, it actually can immensely simplify your code. In this example, you will use a traditional value object (VO) implementation. Value objects are usually accompanied by a data access object (DAO), but you’ll continue to use ProductService.php as the data access object. I will talk more about VO and DAO when we get to the ProductService changes.

For a final example, you’ll map a PHP class named ProductVO.php to an ActionScript 3 class named ProductVO.as. I’ll start with the PHP services to show how you are going to return the ProductVO class.

The following code is the ProductVO.php file. Create a new file called ProductVO.php, and add the code to the file. Upload the file to your amfphp/services/vo/ folder on your web server. You will need to create the vo folder to place the file in. The vo folder is a special folder for AMFPHP in the services directory that does not have the reflection class run on it. Ifyou had hundreds of VO files in the services directory, AMFPHP would try to parse them all when it is first loading.

tmp9d3-19_thumb[2]

The RemoteClass metadata tells Flex to which RemoteObject this class is associated (note that both classes must have the same structure; otherwise, Flex could not cast correctly the RemoteObject).

Creating the data access object

You need to update ProduceService.php to add a method for getting the ProductVO and populating the object. It is common to call the service that performs this function a ProductDAO.php file that has a getProduct method that returns ProductVOs. I highly recommend this naming convention for any application you are developing. However, for simplicity, you’ll just add a getProductVO method to the ProductService.php file.

tmp9d3-20

The addition of the ProductVO import at the beginning of the PHP file is required in order to instantiate the ProductVO class in ProductService.php. The additional function getProductsVO performs the same “select all rows” operation for the database query that the getProducts method performed. The addition is that you first create an array called myProducts. For each row that is returned from the database, you instantiate a new ProductVo and then add the new instance to the myProducts array. When you run out of rows, you return the array of ProductVOs for ActionScript to consume.

Next post:

Previous post: