The DataProviderClass class binds data to a user interface control or other object. Flash Remoting would not be as easy to use if it were not for the hidden functionality of DataProviderClass.
|
DataProviderClass operates behind the scenes on the components listed in Table 11-1.
Component |
Found here |
---|---|
FComboBox |
Flash UI Components |
FListBox |
Flash UI Components |
FTicker |
Flash UI Components Set 2 |
FTree |
Flash UI Components Set 2 |
FTreeNode |
Flash UI Components Set 2 |
FAdvancedCalendar |
Flash UI Components Set 4 |
FSimpleMenu |
Flash UI Components Set 4 |
FSmartComboBox |
Flash UI Components Set 4 |
FDataGrid |
Flash UI DataGrid |
FBarChart |
Flash Charting Components |
FLineChart |
Flash Charting Components |
FPieChart |
Flash Charting Components |
FAccordianPane |
Flash UI Components Set 5 |
FTabView |
Flash UI Components Set 5 |
FWeekView |
Flash UI Components Set 5 |
The RecordSet class inherits from RSDataProviderClass, a class with the same methods as DataProviderClass. RecordSet objects use a format of rows and columns, as do many of the Flash UI components tied to DataProviderClass, so this parallel makes sense.
You can picture a data consumer (the element that consumes the data from the data provider) as shown in Figure 11-1.
Some components support data and label properties, such as the ComboBox and the ListBox. Typically, you store an ID number of some sort in the data property and store the textual representation of the data in the label property. This is roughly the equivalent of a <select> tag in HTML, where your option values are hidden and usually contain numbers. When using the Northwind database as a data provider, it is convenient to use the CategoryID column to populate the data properties and the CategoryDescription column to populate the label properties of the elements within a ListBox or ComboBox, as shown in Table 11-2.
CategoryID (data) |
CategoryDescription (label) |
---|---|
1 |
"Beverages" |
2 |
"Condiments" |
3 |
"Confections" |
4 |
"Dairy Products" |
5 |
"Grains/Cereals" |
6 |
"Meat/Poultry" |
7 |
"Produce" |
8 |
"Seafood" |
Most components that use the DataProviderClass support these methods:
Adds an item to the end of the data set
Adds an item at the specified position in the data set
Returns the length of the data (number of rows)
Removes all rows of data
Replaces an item (row) in the data
Removes a specific item (row)
Sets the data provider for this data consumer
Sorts the items by a specific column in the data
Using setDataProvider( ) on a ComboBox or ListBox, however, displays the entire contents of a recordset row in each line of the ComboBox or ListBox. Therefore, use the DataGlue.bindFormatStrings( ) method to bind a descriptive label and a data item to the rows of ComboBox and ListBox components:
DataGlue.bindFormatStrings(dataConsumer, dataProvider, label, data);
However, you can pass the DataGlue.bindFormatFunction( ) method a custom function to handle the binding of the data. This allows you to load data that does not conform to the label/data structure into a ComboBox or ListBox component. You can create complex structures within the data property of the component rows. DataGlue passes each row of data in the recordset to your format function, which should return an object that looks like this:
{label:yourLabel, data:yourData}
DataGlue hides the details of the binding of the data to the component. Your format function should simply create an object with a label property and a data property. What you put into those properties is up to you.
For example, suppose you want to pass six fields to a Flash movie and display them within a ListBox. You could display one item in the label property and pass the other fields into the data property as an ActionScript object. Figure 11-2 shows the user interface for this demo, which simply displays all of the database fields in text fields as the row is selected in the ListBox.
The code is shown in Example 11-1.
#include "NetServices.as" #include "DataGlue.as" // Set up a responder object to handle recordsets for ListBoxes function ListBoxResponder (lbName) { this.lbName = lbName; } ListBoxResponder.prototype.onResult = function (result_rs) { // Use a format function to bind the data to the individual rows DataGlue.bindFormatFunction(this.lbName, result_rs, formatTheData); }; ListBoxResponder.prototype.onStatus = function (error) { trace(error.description); }; // Create an object to pass to the data property of the ListBox function formatTheData (record) { label = record.ProductName; temp = {}; temp.ProductID = record.ProductID; temp.ProductName = record.ProductName; temp.QuantityPerUnit = record.QuantityPerUnit; temp.UnitPrice = record.UnitPrice; temp.UnitsInStock = record.UnitsInStock; temp.UnitsOnOrder = record.UnitsOnOrder; return {label:label, data:temp} } // Initialization code if (connected == null) { connected = true; NetServices.setDefaultGatewayUrl("http://localhost/flashservices/gateway"); var my_conn = NetServices.createGatewayConnection( ); my_conn.onStatus = errorHandler; var myService = my_conn.getService("com.oreilly.frdg.SearchProducts"); var Products_rs = null; // Main RecordSet object for product list } // Call the service and populate the ListBox myService.getSearchResult(new ListBoxResponder(products_lb)); products_lb.setChangeHandler("updateDisplay"); // Display properties of object contained in data property of the ListBox function updateDisplay (lb) { var record = lb.getSelectedItem( ).data; ProductID_txt.text = record.ProductID; ProductName_txt.text = record.ProductName; QuantityPerUnit_txt.text = record.QuantityPerUnit; UnitPrice_txt.text = record.UnitPrice; UnitsInStock_txt.text = record.UnitsInStock; UnitsOnOrder_txt.text = record.UnitsOnOrder; }
The key to this functionality is the formatTheData( ) function, in which an object named temp is created to hold the data from the record. As you recall, each record is passed to this function by DataGlue. The temp object is populated with data from each individual record of the recordset and packed into the data property of the return value:
return {label:label, data:temp}
The label property simply contains a product name from the recordset.