Join David Gassner for an in-depth discussion in this video Managing data with ArrayList and ArrayCollection, part of Flash Builder 4 and Flex 4 Essential Training.
When you're working with multiple instances of a data object in a Flex application, you typically represent that data in a data collection object. There are two data collection objects in the Flex SDK, designed to work with ordered collections of data, named ArrayList and an ArrayCollection. Both of these classes implement an interface named iList. Because they implement this interface they can be used to contain data in memory, that data can then be presented in visual controls such as the DataGrid component, or the new Flex 4 SDK's List components.
Regardless of whether you work with embedded data as I've already shown you how to do or you retrieve data at runtime from an application server with RPC or Remote Procedure Call components. You want to represent the data in these data collection objects. It makes it very easy to work with the data, both presenting it on screen and making changes to it at runtime. For this demonstration, I'll use an application named DataCollections.mxml. It has an fx:Model tag that's embedding the file products.xml and a DataGrid that's presenting the data on the screen.
I'll show you how to declare an instance of one of these data collection objects. You can do this using either MXML code or ActionScript. I'll show you the MXML version in this application. Both the ArrayList and the ArrayCollection objects are capable of storing data in memory and providing dynamic binding access to that data if it changes at runtime. The ArrayCollection class does a lot more than the ArrayList though. It also implements a number of interfaces that support filtering, sorting, bookmarking and other data manipulation techniques.
In this application, I don't need all the features of the ArrayCollection. So I am going to use this simpler more lightweight component the ArrayList. I'll declare an instance of the ArrayList class. Notice that by default it's declared within the s prefix for Spark. But it's not a visual component, so it must be created within the declarations element. I'll assign it an ID of productCollection. Then I'll set an attribute named source.
The source attribute for both the ArrayList and the ArrayCollection is set to an array. Think of the ArrayList and the ArrayCollection as wrappers around the array that provide more dynamic access to the data. I'll create a binding that references productModel.product and then I'll close the tag. So this is the same expression that I was providing to the DataGrid before but now I'm wrapping the data explicitly in an ArrayList.
I'll go to the DataGrid and change its data provider binding expression, so that instead of referring to the model, it's now referring to the ArrayList , using the expression productCollection. I'll save and run the application. To show you that the functionality is still intact, that the data which is embedded in the application is available and is displayed instantly upon application startup. But now I'll show you some of the dynamic features that are available when you're working with one of these data collections.
Both the ArrayList and the ArrayCollection classes implement an interface named IList as I mentioned before. The IList interface declares a number of valuable methods. These are listed in the Public Methods section of the documentation. You have methods named addItem, addItemAt, getItemAt and so on. I'm going to show you how to use one of these methods, removeItemAt, which requires an index value as an argument.
The index value is the position of the object within the ArrayList or ArrayCollection that you want to remove. I'll go back to the code. In this application, I have a button labeled Remove Item. I'll add a click event handler and have Flash Builder generate a Handler function for it. Then I'll go up to the script section. I'll expand the code to full screen. I'll remove the generated content and then I'll use the following code to remove the item that's currently selected in the DataGrid, productCollection.removeItemAt.
Then I'll pass in the selected index property of the DataGrid, productGrid.selectedIndex. So now, when the user clicks the button that will remove the item from the ArrayList. Now this doesn't affect the model itself. The model has the embedded data. The ArrayList however is dynamic and it can be changed at runtime. I'll save and run the application. I'll click on a row of data and click the Remove Item button and the result is that the data is removed from memory.
I'll click on another and remove that. Now at this point, I am dependent on the user having selected an item from the list. If I click the button without selecting an item, I'll get a runtime error. Notice the error. Index '-1' specified is out of bounds. -1 is the value assigned to selected index by a DataGrid or List control when nothing is selected. So, I am going to prevent this error from happening. I could wrap the removeItemAt call within the click handler within a conditional block to check the selected index.
But a possibly better approach would be to disable the button completely if the user hasn't selected anything. So I'll place the cursor inside the tag for the Button and use the enabled property and I'll set it's value to a binding expression that looks like this. productGrid.selectedIndex != -1. The selected index property of the DataGrid control is bindable, so when it's value changes at runtime, it will report that change to any binding expressions, such as this one.
Now, the button will be enabled only when the user has clicked on an item. I'll run that application and noticed that the button is initially disabled. I'll click on an item and that enables the button. I'll click to remove the item and it's disabled again. You can use this sort of binding expression technique to enable and disable visual controls based on the current state of other visual controls such as DataGrid or a List. So in this demonstration, I've shown you how to create a data collection object using MXML code.
I used the ArrayList component. But if you need the additional capabilities of ArrayCollection you can use that instead. I've also shown you how to wrap a bit of data inside the ArrayList, using its source attribute. Then how to present that data visually using the DataGrid or some other visual control from the Flex SDK. I have also shown you that you can interact with the data, calling methods of the IList interface such as the removeItemAt method that I am calling here. I encourage you to explore the documentation for both the ArrayList and the ArrayCollection classes.
These are very important classes for data centric Flex applications that you use to store your data in memory at runtime.
- Understanding the history of Adobe Flex
- Installing the Flash Builder components
- Using Eclipse views and editors
- Programming with MXML and integrating MXML and ActionScript
- Debugging Flex applications
- Adding visual controls to a Flex application interface
- Displaying images and dynamic data
- Formatting with CSS
- Skinning Spark components with MXML graphics
- Creating data entry form components
- Integrating with Apache, PHP and MySQL
Skill Level Beginner
Q: After importing the Debugging.fxp file following the steps outlined in the “Importing and exporting projects as FXP files” video, several of the applications will not run.
When I attempt to debug or run the Variables.mxml or Watchpoints.mxml applications, I am unsuccessful. Pressing F11 to debug causes Flex to look for an application it CAN run, and runs that one. If I Right-Click one of the aforementioned applications and then click Run Application, an error appears that says “This file cannot be launched.”
What is causing this problem?
A: This is a common issue with Flash Builder. Before pressing F11 (or right-clicking and choosing Run Application), set the current MXML application file as the "default" by right-clicking it and choosing "Set as default application".
This should ensure that the application you want to preview opens in the browser when you press F11.
Q: When trying to specify the fontStyle as italic in both ways described in the first and second videos of the “Using Cascading Style Sheets (CSS)” chapter, only the literal string "italic" seems to work. If I use the constant for the same value like this:
I get a warning that reads:
"Design mode: Error during component layout. Choose Design > Refresh to refresh design mode."
Even if I try to refresh, design mode will not work until I change it back to the literal string. I made sure the import for this namespace was there by pressing Ctrl+spacebar, refreshed design mode several times, and even restarted Flash Builder. However, the only solution seems to be to use the literal. Is there a fix for this?
A: The use of constants and bindings in MXML style attributes results in unpredictable results in Design View, as evidenced by this error. Unfortunately, the best you can expect is that design view will render the presentation, but won't show the results of the style setting, because Design View isn't capable of evaluating MXML bindings without the benefit of Flash Player's runtime capabilities.
Q: Is Flash Builder compatible with Mac OS X 10.7 (Lion)?