Requirements

Prerequisite knowledge

Read Part 1 and Part 2 of this series. Additionally, to complete the steps in this tutorial you’ll first need to complete the steps outlined in Part 2.

User level

Beginning

Part 1 of this series covered the basics working with data using the new data-centric development features of Flash Builder 4. Part 2 took it a step further by introducing Flash Remoting and Zend AMF to exchange data with a PHP back end. In this article I will provide an overview of some of the advanced data features in Flash Builder 4 for implicit paging and data management, which you can use to make your applications more intuitive and more robust.

Implicit paging

Think about an application that will be dealing with thousands of database records. How should that data appear to the user? Does the user need to be able to see every row? Could a DataGrid fit thousands of rows? Does it make sense to send thousands of rows at a time to your application from the server? Implicit paging can help your application handle these issues.

With implicit paging, a Flex application requests only the rows from the server that the user is going to see. As the user scrolls down a DataGrid, for example, Flex automatically figures out which records are visible and requests those from the server. To the user, it appears that all of the data is already in the application. Your application, though, is only requesting exactly what the user sees.

Looking through the forests

Take a look at the methods from the PHP ForestService class you used in Part 2. You'll see that some of the methods that correspond to basic CRUD (create, read, update, delete) operations. You'll also notice a couple of extra methods, including getForestsPaged() and count(). The getForestsPaged() method takes two parameters that help request the correct records: startIndex and numItems. That method allows you to specify a starting point and a specific number of records to bring back. When you attach this method to a Flex DataGrid, it will automatically be called with the correct parameters based on how the user scrolls through the data.

Enabling implicit paging

Starting with where you left on in Part 2, follow these steps to enable implicit paging:

  1. Choose Window > Data/Services to display the Data/Services panel.
  2. In the Data/Services panel, right-click the getForestsPaged() method and select Configure Input Types.
  3. Select int as the type for both startIndex and numItems and click OK.

    If the return type for getForestsPaged() is Object, you’ll need to configure the return type as well.

  4. Right-click the getForestsPaged() method again and select Configure Return Type.
  5. Follow the procedure for auto-detecting the return type as outlined in Part 1. This time you’ll need to supply parameters for the call; you can use 1 and 2 for startIndex and numItems, respectively.

    Now you’re ready to enable implicit paging.

  6. Right-click the getForestsPaged() method and select Enable Paging.
  7. Select id as the property that uniquely identifies this data type.
  8. Click Next.
  9. Select count() as the Count Operation; this function provides the application with the total number of records.
  10. Set the Page Size to 5 and click Finish (see Figure 1).

Connecting to a DataGrid

You can now bind the getForestsPaged() operation to a user interface element.

  1. Switch to Design view.
  2. Drag a DataGrid from the Components panel to the main area of the screen.
  3. Drag the getForestsPaged() operation from the Data/Services panel to your DataGrid.
  4. In the Bind To Data dialog box, click OK to generate a new service call.
  5. Choose File > Save to save your project changes.
  6. Choose Run > Run MyFirstZendAMFApplication to run the application.

When you run your application and scroll through the data, your server will send only the rows that you're currently on. As a result your application is much more responsive because it is not dealing with (potentially) thousands of rows. Another bonus is that this works with any of the data-centric development service types, including HTTPService.

Creating a better master-detail form

Now that you’ve create a paged DataGrid, the next step is to let users modify the data. Just as you did in Part 1, you can create a master-detail form to enable a user to display and update the data:

  1. Right-click the DataGrid and click Generate Details Form.
  2. In the Generate Form dialog box, keep the defaults and click Finish (see Figure 2).

As before, when you run the application your DataGrid will automatically fill with data, and as you scroll down it will grab records from the server in increments that you set on the getForestsPaged() operation. Now, when you click on a row, that record’s data will fill the form.

When you change data in the form and click Submit it will change in the DataGrid, but no calls are made to the server, so the database remains unmodified. For that you'll need to dive into some code.

Up to now the code has all been generated by Flash Builder 4. In this case you're going to write a bit to save changes that are made in the DataGrid to the server.

  1. In Design view, drag a button next to the master-detail form.
  2. Select the button in Design view so you can use the Properties panel to make changes.
  3. For the button’s id, type btn_save.
  4. For its label, type Save.
  5. Click the lightning bolt next to On Click and select Generate Service Call (see Figure 3).
  6. In the Generate Service Call dialog box, select updateForest() as the operation to call when the button is clicked. Click OK.
  1. When Flash Builder 4s witches to Code view, edit the event handler so that it makes the following call:
updateForestResult.token = forestService.updateForest(nationalForest);
  1. Save the project.

For the call to updateForest() in the event handler for the button, you need to provide a variable that represents the object to be updated. The form and the DataGrid are using a powerful Flex feature called data binding. There is a central object that represents the data in the form. In this application the code for that object is:

<valueObjects:NationalForest fx:id="nationalForest" />

When an item is selected in the DataGrid, it updates this object and the form is bound to the object. So all the save function has to do is send that object to the server, because it represents the updated values in the form. The code below shows the event handlers and the service/object code:

<fx:Script> <![CDATA[ import mx.controls.Alert; import mx.events.FlexEvent; protected function dataGrid_creationCompleteHandler(event:FlexEvent):void { getForestsPagedResult.token = forestService.getForestsPaged(); } protected function button_clickHandler(event:MouseEvent):void { nationalForest.id = parseInt(idTextInput.text); nationalForest.area = parseFloat(areaTextInput.text); nationalForest.name = nameTextInput.text; nationalForest.closest_city = closest_cityTextInput.text; nationalForest.state = stateTextInput.text; nationalForest.established = establishedDateField.selectedDate; } protected function btn_save_clickHandler(event:MouseEvent):void { updateForestResult.token = forestService.updateForest(nationalForest); } ]]]]> </fx:Script> <fx:Declarations> <s:CallResponder id="getForestsPagedResult"/> <forestservice:ForestService id="forestService" fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)" showBusyCursor="true"/> <valueObjects:NationalForest fx:id="nationalForest"/> <s:CallResponder id="updateForestResult"/> <!-- Place non-visual elements (e.g., services, value objects) here --> </fx:Declarations>

Now your application can retrieve paged records, modify them locally, and send them to the server when you make changes. This is a good introduction to data management. When the user edits a form field to change a record, it is changed in the DataGrid, but it is not sent to the server. The only time a record on the server will be changed is when the user clicks the Save button. It would be helpful if the user could queue up several changes and then either send them all to the server when finished or revert back to the original data without ever making changes on the server. That is where data management comes in.

Introducing data management

There are many situations in which a user may want to manipulate the data before actually sending it to the server. For example, the user may be offline or they may simply want to test some ideas out with different data sets. This is where data management can help. Flash Builder 4 makes it easy to add client-side data management to a Flex application. You can enable your users to make changes to data within the Flex application and then submit those changes in a batch or roll back changes to the data from the server.

This can also be an advantage in terms of reducing network traffic. When the user has to make a request to the server and receive a response each time they want to change the data that can add up to heavy network traffic. Data management makes it possible to make multiple changes in one batch.

It can also take a lot of code to manage multiple objects. Not only do you have to write the code for the CRUD methods for each object, you also have to write the code that handles the operations. Think about the code to deal with the results and faults with each operation. The data management features in Flash Builder 4 simplify much of this. Instead of thinking about handlers, the UI components bind to the objects themselves and the operations map to specific tasks for those objects.

Follow these steps to enable data management for this application:

  1. As a preliminary step, you need to configure the input type for deleteForest() operation.
  2. Right-click deleteForest() in the Data/Services panel and select Configure Input Types.
  3. Select int as the type for the id parameter and click OK.
  4. In the Data/Services panel, right-click the getForestsPaged() operation and select Enable Data Management.
  5. In the Data Management dialog box, select id as the identity property and click Next.
  6. You’ll now to need to map the operations of the service to the typical CRUD operations. It should be fairly obvious which operations map to each item in the list (see Figure 4).
  7. Click Finish.

One handy feature of the Flex DataGrid is the ability to edit data directly in the grid. Combining this feature and data management, you enable the user to edit data right in the DataGrid and then send all the record changes at once.

  1. In Design view, select the DataGrid. Then, in the Properties panel, set its Editable property to true.
  2. Next, switch to Code view, and edit the event handler for the Save button. Replace the existing call to

    forestService.updateForest(nationalForest) with a call to forestService.commit().

    The commit() method was introduced when you enabled data management; it lets the user update all of the records that have changed.

    The next step is to let the user revert back and undo any changes that they've made. With data management this can be accomplished without any trips to the server. The application keeps track of all the changes and can go back to the original data set when needed.

  3. To create a revert button, drag another button to Design view, set its id to btn_revert, and set its label to Revert.
  4. Click the lightning bolt next to On Click and select Generate Event Handler.
  5. When Flash Builder 4 switches to Code view, insert a call to forestService.revertChanges(); in the event handler.
  6. Save your project.

The complete code for the Save and Revert button event handlers is shown below:

protected function btn_save_clickHandler(event:MouseEvent):void { forestService.commit(); } protected function btn_revert_clickHandler(event:MouseEvent):void { forestService.revertChanges(); }

Where to go from here

Now you have an application that provides more responsiveness with implicit paging as well as a more robust way to handle data with data management. These are two of the most powerful data-centric development features of Flash Builder 4. I encourage you to explore some of the code that Flash Builder 4 generated and examine some of the methods that were created as part of enabling data management. That will give you a head start on customizing this sample application for your own purposes.

For more on data-centric development, see these Adobe Developer Connection articles: