One data collection to rule them all, or Simulating SQL queries in Flex

· Flex
Authors
Many times in the process of developing user interfaces I’ve needed to use the same base data in multiple views.  For instance, say I have a collection of books stored in my model. In one view I may have the newest books while in another I could just be showing books by a certain author. In the following example I show what happens when you try to use one collection in several views.

BookVO Class

1
2
3
4
5
6
7
8
9
package
{
[Bindable]
public class BookVO
{
public var title:String = "";
public var author:String = "";
}
}

Figure 1.

Code 1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?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/halo"
               xmlns:local="*" viewSourceURL="srcview/index.html">
    <fx:Declarations>
        <s:ArrayCollection id="model">
            <local:BookVO title="One Day at a Time"
                          author="Danielle Steele"/>
            <local:BookVO title="The Lost Symbol"
                          author="Dan Brown"/>
            <local:BookVO title="The Girl with the Dragon Tattoo"
                          author="Stieg Larsson"/>
            <local:BookVO title="Shanghai Girls"
                          author="Lisa See"/>
            <local:BookVO title="Crossroads"
                          author="Belva Plain"/>
            <local:BookVO title="Cutting for Stone"
                          author="Abraham Verghese"/>
            <local:BookVO title=" Precious"
                          author="Sapphire"/>
            <local:BookVO title="The Man from Beijing"
                          author="Henning Mankell"/>
            <local:BookVO title="Olive Kitteridge"
                          author="Elizabeth Strout"/>
            <local:BookVO title="Hotel on the Corner of Bitter and Sweet"
                          author="Jamie Ford"/>
        </s:ArrayCollection>
    </fx:Declarations>

    <s:layout>
        <s:VerticalLayout gap="5"
                          paddingBottom="5"
                          paddingLeft="5"
                          paddingRight="5"
                          paddingTop="5"/>
    </s:layout>

    <mx:DataGrid dataProvider="{model}"
                 width="100%"
                 height="100%"/>
    <mx:DataGrid dataProvider="{model}"
                 width="100%"
                 height="100%"/>

</s:Application>
The trouble begins when you try sorting the books. Sorting one grid causes the other to be affected by the same sort. Both share the same dataProvider and when you click the header of one, it applied a new sort to the ArrayCollection of books. So how do we avoid this issue? The answer is pretty simple. If you look at the Flex Language Reference you will notice that ArrayCollection extends ListCollectionView. This kind of gives you a better idea of what the ArrayCollection is for. Essentially, it should be used to wrap your model collection in a “data view”. We’re going to replace the <s:ArrayCollection /> with <s:ArrayList />. Create an ArrayList as the base model, then wrap in a couple ListCollectionViews—the slightly lighter-weight version of ArrayCollection. Check out the Figure 2 to see the results.

Figure 2.

Code 2.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?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/halo"
               xmlns:local="*">
    <fx:Declarations>
        <s:ArrayList id="model">
            <local:BookVO title="One Day at a Time"
                          author="Danielle Steele"/>
            <local:BookVO title="The Lost Symbol"
                          author="Dan Brown"/>
            <local:BookVO title="The Girl with the Dragon Tattoo"
                          author="Stieg Larsson"/>
            <local:BookVO title="Shanghai Girls"
                          author="Lisa See"/>
            <local:BookVO title="Crossroads"
                          author="Belva Plain"/>
            <local:BookVO title="Cutting for Stone"
                          author="Abraham Verghese"/>
            <local:BookVO title=" Precious"
                          author="Sapphire"/>
            <local:BookVO title="The Man from Beijing"
                          author="Henning Mankell"/>
            <local:BookVO title="Olive Kitteridge"
                          author="Elizabeth Strout"/>
            <local:BookVO title="Hotel on the Corner of Bitter and Sweet"
                          author="Jamie Ford"/>
        </s:ArrayList>
        <mx:ListCollectionView id="collection1" list="{model}" />
        <mx:ListCollectionView id="collection2" list="{model}" />
    </fx:Declarations>
   
    <s:layout>
        <s:VerticalLayout gap="5"
                          paddingBottom="5"
                          paddingLeft="5"
                          paddingRight="5"
                          paddingTop="5"/>
    </s:layout>
   
    <mx:DataGrid dataProvider="{collection1}"
                 width="100%"
                 height="100%"/>
    <mx:DataGrid dataProvider="{collection2}"
                 width="100%"
                 height="100%"/>
   
</s:Application>
Apart from separate sorts, you can also apply filters to the ListCollectionViews without affecting the other view. However, if you add or remove an item from one view, both collections will be updated.  It’s kinda a best of both worlds between binding and SQL.

3 Comments

Comments RSS
  1. johnnygod

    Nathan,

    What is /&gt in these examples ?

    • Nathan

      Hey Johnny,
      Sorry about that. It seems something fudged up my code samples. It should be more understandable now.

  2. Dip

    Many Thanks for sharing this, Adobe docs does suggest new instance of ListCollectionView for each UI View, here you have shown us how to do it.

Leave a Comment


*