Friday, July 1, 2011

XML in Flex: Part 5 - Using XMLListCollection

In the previous tutorials, we have learned how to access the XML data that we load into our application. Once the data is loaded, we need to operate with it and, most of the time, display the information to the user. One way of doing this is using the XMLListCollection class.

Before we start talking about XMLListCollection, we need to know what an XMLList is. XMLList is a class, which represents an object that contains one or more XML objects in it. Using this class, we can turn multiple XML objects into a group and work with the elements individually, or with the group as a whole.

XMLListCollection is a special class that holds and organizes XMLLists. Using this class, we can sort and filter the said XMLList objects.

I will assume that you have read my previous tutorials on XML in Flex, and have the code from the previous tutorial. This is where we will start off.

First we need to create a new variable typed XMLListCollection. Because my XML is a list of products, I will call this variable products.

import mx.collections.XMLListCollection;

private var products:XMLListCollection;

Let's add a [Bindable] metatag to this variable. By doing that, we will tell Flex to keep an eye on this variable and any changes that are made to it. If there has been a change in the products variable - everything that is related to this variable will also be updated to represent the new fresh updated data.

import mx.collections.XMLListCollection;

[Bindable]
private var products:XMLListCollection;

So far your fx:Script tags look like this:

<fx:Script>
<![CDATA[
import mx.collections.XMLListCollection;
import mx.rpc.events.ResultEvent;

[Bindable]
private var products:XMLListCollection;

private function handleResults(evt:ResultEvent):void {
myLabel.text = evt.result.product[0].name;
}
]]>
</fx:Script>

We will remove the myLabel label object and the line that updates its text value. Instead, we will create a new List object, which will display each XMLList (aka each product) as a separate list object. See where I'm going with this?

Let's do everything step by step. Firstly we need to set a value to our products variable. We do this once the access to the data is gained - in the handleResults() function. We create a new XMLListCollection object with the array of products as the parameter and set it as the value of the variable. In the end, the code will look like this:

<fx:Script>
<![CDATA[
import mx.collections.XMLListCollection;
import mx.rpc.events.ResultEvent;

[Bindable]
private var products:XMLListCollection;

private function handleResults(evt:ResultEvent):void {
products = new XMLListCollection(evt.result.product);
}
]]>
</fx:Script>

Now, lets create a List component. This is an object that has a property called dataProvider, which is also used for other components, like DataGrid. We set this property to our products variable, and lets see what happens.

<s:List dataProvider="{products}">
 <s:layout>
  <s:HorizontalLayout />
 </s:layout>
</s:List>



The list component displays the content of each product node in the XML file as text, we don't really want that. Let's make it only display the name of each product. This can be done using the labelField property of the List object.

<s:List dataProvider="{products}" labelField="name">
 <s:layout>
  <s:HorizontalLayout />
 </s:layout>
</s:List>

And the application now looks like this:



The whole code:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx"
      creationComplete="myData.send();">
   
<fx:Declarations>
<s:HTTPService id="myData" url="C:\Users\7 User\Documents\kirill\flexdev\src\products.xml" result="handleResults(event)" resultFormat="e4x" />
</fx:Declarations>

<fx:Script>
<![CDATA[
import mx.collections.XMLListCollection;
import mx.rpc.events.ResultEvent;

[Bindable]
private var products:XMLListCollection;

private function handleResults(evt:ResultEvent):void {
products = new XMLListCollection(evt.result.product);
}
]]>
</fx:Script>

<s:List dataProvider="{products}" labelField="name">
 <s:layout>
  <s:HorizontalLayout />
 </s:layout>
</s:List>

</s:Application>

That's all for today's tutorial!

Thanks for reading!

Related:

XML in Flex: Part 1 - The fx:Model tag
XML in Flex: Part 2 - The fx:XML tag
XML in Flex: Part 3 - Loading XML at runtime
XML in Flex: Part 4 - Using the XML loaded at runtime

3 comments:

Anonymous said...

Great step by step instructions! Was very helpful!

Anonymous said...

result="handlesResult(evt)" is not getting called

Any suggestions

Ram Kaarthik said...

I worked. It was a good article. My XML was not formed correctlt.

Post a Comment