Array vs. ArrayCollection in Flex 2 (with a ColdFusion Slant)

来源:互联网 发布:amos软件怎么读 编辑:程序博客网 时间:2024/06/10 20:58
I've been spending a bit of personal time digging into Flex 2 development. One thing I've noticed up front is that there's an important distinction between using an Array and an ArrayCollection when coding your applications. This is an important point for ColdFusion developers because, in CF, we only have an Array datatype while most other languages (Java, C#, etc.) have an explicit ArrayCollection class. Further, since Flex is simply a front-end development language, you're likely to be doing lots of talking to a back-end technology to return data sets and the like.

So what's the difference? Well, the LiveDocs entry for the ArrayCollection class sums it up pretty well, so here it is:

 

The ArrayCollection class is a wrapper class that exposes an Array as a collection that can be accessed and manipulated using the methods and properties of the ICollectionView or IList interfaces. Operations on a ArrayCollection instance modify the data source; for example, if you use the removeItemAt() method on an ArrayCollection, you remove the item from the underlying Array.

The first sentence in that explanation is the key: The ArrayCollection class is simply a wrapper around the Array class. So if they're both Arrays at some level, why is this important? Well, with a standard Array, what you have available to you are the basic methods and properties that you'd expect in any language: push() (for adding an element to the end), pop() (for removing the last element), length (the number of indices), etc. However, the ArrayCollection class provides a suite of immensely convenient "extra" methods that can act on the Array.

For example, say I have an array with the values in the color spectrum:

 

var spectrumColors:Array = ["red","orange","yellow","green","blue","indigo","violet"];

(Quick side note to ColdFusion developers: Arrays in ActionScript are zero-based. So, to directly access the element "red", you'd use spectrumColors[0] rather than spectrumColors[1] like you would in ColdFusion.)

However, Stephen Hawking releases a new theory that there's no such thing as "green," and mandates that it should be removed from the color spectrum. How would you do it using the Array class? Honestly, it's not worth getting into the code because it's a waste of keystrokes. However, there's a really easy way to do this: Use the ArrayCollection class. The ArrayCollection class extends the ListCollectionView class. Without getting into the boring details, the ListCollectionView class has a bunch of extremely handy methods for manipulating its elements, namely the addItemAt(), removeItemAt(), and getItemAt() methods. Going back to our example, if the spectrumColors variable is datatyped as being an ArrayCollection, accomodating Mr. Hawking becomes immensely easier:

 

var spectrumColors:ArrayCollection = ["red","orange","yellow","green","blue","indigo","violet"];

spectrumColors.removeItemAt(spectrumColors.getItemIndex("green"));

All the code above does is create the spectrumColors variable of type ArrayCollection, and then removes the item from the array based on the returned index value that matches the value "green." See? Easy. No need to manually loop over the array to find an index or verbose constructs like that.

OK, so I promised a ColdFusion slant in the post title. Now that you have an understanding of Array vs. ArrayCollection, let's see how this fits in to ColdFusion and Flex.

Flex is all about providing a rich user interface for our users. However, the key phrase in that sentence is "user interface." Flex does not provide any native database connectivity, so you need a back-end technology to do the "heavy lifting" and return the results to Flex for display. The ColdFusion team did a phenomenal job of making Flex/ColdFusion integration as seamless as possible in the 7.0.2 release. However, there are certain nuances that we need to keep in mind when working between these two technologies. One such nuance is the fact that it's one thing to query for data and return it as-is to the calling environment (ColdFusion), but it's another to be able to use advanced concepts such as run-time sorting and filtering for display (Flex). To that end, certain Flex 2 framework components use what are known as data providers to not only display the result set, but to further allow the user to manipulate the results to their liking. To that end, the Flex engineers cleverly implemented these framework components such that you could either use the raw datatype returned or you could use a collection instead, which allows for more advanced access to the data set. Hopefully my above explanation regarding the difference between an Array and and ArrayCollection sufficiently shows the difference between a datatype and its Collection wrapper class. You could use a basic Array (the raw datatype) to display a result set, if that's all you want to do. But to provide more advanced interaction, these raw datatype classes don't provide the necessary advanced access or event broadcasts necessary. So you're going to need to convert the datatype that comes back from your back-end (i.e., ColdFusion) into the appropriate collection type so that it can then be used for display, thereby offering some of the more advanced features that the Flex framework provides.

While there are many controls that use data providers, I'm going to use the DataGrid in my example because that seems to be the most common way of displaying tabular data in Flex. If I want to display a datagrid consisting of some basic company information: company name, address, etc., below is the ActionScript code needed to take the returned results into the appropriate collection datatype. Assume that a ColdFusion query is being returned.

 

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" initialize="myService.send()">

<mx:Script>
<![CDATA[
   import mx.collections.ArrayCollection;
   import mx.rpc.events.ResultEvent;
   
   [Bindable]
   private var companyInfo:ArrayCollection;
   
   private function resultHandler(event:ResultEvent):void {
    companyInfo = event.result as ArrayCollection;
   }
]]>
</mx:Script>

<mx:HTTPService id="myService" url="url/to/cfc?WSDL" result="resultHandler(event);" />

<mx:DataGrid dataProvider="{companyInfo}" />

</mx:Application>

As you can see the above code simply takes the query returned from ColdFusion ("event.result") and "coerces" it (or casts it) to an ArrayCollection using the as keyword. The framework takes care of everything else for you. Then I simply assign the companyInfo variable as the data provider for the DataGrid. If I now wanted to add more advanced functionality, such as filtering or editing, to the result set, I already have the results in the appropriate format. I just need to write a function that acts as the filter or "listens" for the updated data. The Adobe LiveDocs resource provides a great example of providing this sort of functionality.

Hopefully this provides a basic understanding of the difference between datatypes and their associated Collection classes, and when each one should be used.

 

原创粉丝点击