→ Пошук по сайту       Увійти / Зареєструватися
Знання Adobe Flex — технологія швидкої розробки RIA

Ієрархічні об'єкти даних

 Flex  RIA  Flash

Про ієрархічні об’єкти даних

Ієрархічні об'єкти даних використовуються з елементами контролю, які відображають вкладену ієрархію вузлів і підвузлів, таку, як гілки дерева і листки, а також підменю меню і елементи. Наступні елементи керування використовують ієрархічні об'єкти даних:

  • Меню (Menu)
  • Полоса меню (MenuBar)
  • Кнопка вспливаючого меню (PopUpMenuButton)
  • Дерево (Tree)

Всі ієрархічні компоненти використовують однаковий механізм для роботи з джерелом даних. Наступні приклади використовують елемент керування деревом (Tree), але приклади застосовують і до інших компонентів.

Flex за замовчуванням підтримує два типи ієрархічних об'єктів даних.

XML може бути : рядками (Strings), що містять добре сформовану мову XML; або об’єктами XML, XMLList або XMLListCollection, включаючи об'єкти, породжені тегами і , що виконуються під час компіляції. (Ці теги підтримують прив’язку даних, яку не можна виконати безпосередньо в ActionScript.) Щоб відобразити вкладену ієрархію XML, Flex може автоматично структурувати дерево або елемент контролю на основі меню.

Об’єкти можуть бути будь-якою сукупністю вкладених об'єктів або підкласів об’єкту (в тому числі масиви (Arrays) або об’єкти сукупності масивів (ArrayCollection), які мають структуру, в якій дочірні елементи вузла знаходяться в дочірньому полі. Для отримання додаткової інформації див. Creating a custom data descriptor. Для створення вкладених об'єктів, які підтримують прив'язку даних можна також використовувати тег , що виконуються під час компіляції. Але при тому потрібно слідувати структурі, визначеній в розділі Using the tag with Tree and menu-based controls.

Можна додати підтримку для інших структур ієрархічного постачання [джерела] даних, таких як вкладені об'єкти, де дочірні елементи можуть перебувати в полях зі змінними іменами.

Дескриптори даних і ієрархічна структура даних

Ієрархічні дані, що використовуються в дереві і елементах керування на основі меню, повинні бути у формі, яка може бути проаналізована і регульована [керована] за допомогою класу дескриптора [описувача] даних. Дескриптор даних — це клас, який забезпечує інтерфейс між ієрархічним керуванням і об'єктом джерела даних (Data Provider). Він реалізує набір елементів керування певних методів для визначення структури і інформаційного наповнення [контенту] джерела даних; для отримання, додавання і видалення даних; а також для зміни властивостей даних з особливим контролем.

Flex визначає два інтерфейси дескрипторів даних для ієрархічних елементів керування:

Методи ITreeDataDescriptor, які використовуються елементами керування дерева (Tree) Методи IMenuDataDescriptor для елементів керування меню (Menu), полосою меню (MenuBar) і кнопкою вспливаючого меню (PopUpMenuButton)

Структура Flex забезпечує клас DefaultDataDescriptor, який реалізує обидва інтерфейси. Можна використовувати властивість dataDescriptor для визначення класу опису даних користувача, який обробляє моделі дані, які не відповідають структурі дескриптора за замовчуванням.

Методи дескриптора даних і вимоги до джерела

Наступна таблиця описує методи обох інтерфейсів, і поведінку [характер зміни] класу DefaultDataDescriptor. Перший рядок кожного запису інтерфейсу/ методу показує, чи цей метод належить інтерфейсу ITreeDataDescriptor, інтерфейсу IMenuDataDescriptor, або обом інтерфейсам, а отже, вказує, чи цей метод використовується для дерев, меню, або разом і для дерев, і для меню.

МетодПовертаєПоведінка DefaultDataDescriptor
hasChildren(node, [model]) Змінна типу Boolean, яка вказує, чи є вузол гілкою з дочірніми елементами Для XML повертає істину, якщо вузол має хоча б один дочірній елемент.
getChildren(node, [collection]) Дочірній елемент вузла. Для XML повертає XMLListCollection з дочірніми елементами. Для інших об'єктів повертає вміст поля дочірніх елементів вузла.
isBranch(node, [collection]) Чи є вузол гілкою. Для XML повертає істину, якщо вузол має принаймні один дочірній елемент, або якщо він має атрибут isBranch.Для інших об'єктів повертає істину, якщо вузол має поле isBranch.
getData(node, [collection]) Дані вузла. Повертає вузол.
addChildAt(node, child, index, [model]) Змінна типу Boolean, яка вказує, чи був успішним процес. У всіх випадках вставляє вузол як дочірній об'єкт перед вузлом в місцезнаходження індексу в даний час.
removeChildAt(node, index, [model])Змінна типу Boolean, яка вказує, чи був успішним процес. Для всіх випадків переміщує дочірній елемент вузла в місцезнаходження індексу.
getType(node)(IMenuDataDescriptor only) Рядок з вузлом типу меню. Багатозначні елементи — check, radio і separator.Для XML повертає значення атрибуту типу вузла.Для інших об’єктів повертає вміст поля типу вузол.
isEnabled(node)(IMenuDataDescriptor only) Змінна типу Boolean, яка вказує, чи вузол меню активований [дозволений]. Для XML повертає значення активованого [дозволеного] атрибуту вузла.Для інших об’єктів повертає вміст активованого поля вузла.
setEnabled(node, value)(IMenuDataDescriptor only)  Для XML встановлює значення вибраного атрибуту вузла в істинне (true) або неістинне (false).Для інших об’єктів встановлює вміст активованого поля вузла.
isToggled(node)(IMenuDataDescriptor only) Змінна типу Boolean, яка вказує, чи вибрано вузол меню. Повертає значення переключеного атрибуту вузла.
setToggled(node, value) (IMenuDataDescriptor only)  Для XML встановлює значення вибраного атрибуту вузла в істинне (true) або неістинне (false). Для інших об’єктів встановлює вміст активованого поля вузла.
getGroupName(node) (IMenuDataDescriptor only) Назва групи селективної кнопки (radio button), до якої належить вузол. Для XML повертає значення атрибуту groupName вузла.Для інших об’єктів повертає вміст поля groupName вузла.

Наступний об’єкт, який наведений у приклад, має структуру джерела даних для керування деревом, і коректно оброблюється класом:

 [Bindable]
public var fileSystemStructure:Object = 
    {label:"mx", children: [
        {label:"Containers", children: [
            {label:"Accordian", children:[]},
            {label:"DividedBox", children: [
                {label:"BoxDivider.as", data:"BoxDivider.as"}, 
                {label:"BoxUniter.as", data:"BoxUniter.as"}]},
            {label: "Grid", children:[]}]},
        {label: "Controls", children: [
            {label: "Alert", data: "Alert.as"},
            {label: "Styles", children: [
                {label: "AlertForm.as", data:"AlertForm.as"}]},
            {label: "Tree", data: "Tree.as"},
            {label: "Button", data: "Button.as"}]},
        {label: "Core", children:[]}
    ]};

Для об'єктів корінь [кореневий каталог] є екземпляром об'єкта, так що завжди повинен бути єдиний корінь (як з XML). Можна також використовувати масив, що містить вкладені масиви, в якості джерела даних. В цьому випадку джерело не має кореня, кожен елемент у верхньому рівні масиву з'являється на верхньому рівні керування.

DefaultDataDescriptor може належним чином описати [врегулювати] добре сформовані вузли XML. Метод IsBranch (), однак, повертає істину, тільки якщо вузол параметра має дочірні вузли або якщо вузол має атрибут isBranch зі значенням істина (true). Тому якщо XML- об'єкт використовує будь-який метод, крім істинного атрибуту isBranch для визначення порожньої гілки, необхідно створити користувацький дескриптор даних.

DefaultDataDescriptor належним чином обробляє сукупності. Наприклад, якщо властивість дочірніх елементів вузла є екземпляром ICollectionView, метод getChildren () повертає дочірні об’єкти як об'єкти ICollectionView.

Використання тегу з деревовидними елементами контролю та елементами контролю на основі меню

Тег дозволяє визначити структуру джерела даних в MXML. Компілятор Flex конвертує вміст тегу в ієрархічний граф об’єктів ActionScript. Тег має дві переваги над визначенням джерела даних об’єкту в ActionScript.

  • Можна визначити структуру шляхом використання легкочитаємого формату, подібному XML.
  • Можна прив’язати записи структури до змінних ActionScript, так що можна використати для створення джерела даних на основі об’єкту, яке отримує дані з складних динамічних джерел.

Щоб використати тег з елементом керування, який використовує дескриптор даних, згенерований компілятором об’єкт повинен відповідати вимогам дескриптора даних, як розглянуто в розділі Data descriptors and hierarchical data structure. Так само, як з об’єктом XML, тег повинен мати єдиний кореневий елемент.

У більшості ситуацій замість використання тегу потрібно розглядати використання тегу або , як описано в розділі XML-based data objects. Засновані на XML теги підтримують прив'язку даних до елементів, а клас DefaultDataDescriptor підтримує всі добре структуровані XML. Тому можна використовувати більш природну структуру, де назви вузлів можуть представити свою функцію, і тоді не потрібно штучно назвати дочірні вузли.

Щоб використовувати тег як джерело даних для елементу керування, який використовує клас DefaultDataDescriptor, всі дочірні вузли повинні називатися дочірніми. Ця вимога відрізняється від структури, яка використовується з об'єктом, де масив, який містить дочірні об'єкти, називається дочірнім.

Наступний приклад показує використання тегу з прив'язкою даних як з джерелом даних для меню, і показує, як можна динамічно змінити структуру меню:

<?xml version="1.0"?>
<!-- dpcontrols\ModelWithMenu.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*">
    <mx:Script>
        <![CDATA[
            import mx.controls.Menu;
            public var productMenu:Menu;

            public function initMenu(): void
            {
                productMenu = Menu.createMenu(null, Products.Department);
                productMenu.setStyle("disabledColor", 0xCC3366);
                productMenu.show(10,10);
            }
        ]]>
    </mx:Script>
    <mx:Model id="Products">
        <Root>
            <Department label="Toys">
                <children label="Teddy Bears"/>
                <children label="Action Figures"/>
                <children label="Building Blocks"/>
            </Department>
            <Department label="Kitchen">
                <children label="Electronics">
                    <children label="Crock Pot"/>
                    <children label="Panini Grill"/>
                </children>
                <children label="Cookware">
                    <children label="Grill Pan"/>
                    <children label="Iron Skillet" enabled="false"/>
                </children>
            </Department>
            <!-- The items in this entry are bound to the form data -->
            <Department label="{menuName.text}">
                <children label="{item1.text}"/>
                <children label="{item2.text}"/>
                <children label="{item3.text}"/>
            </Department>
        </Root>
    </mx:Model>

    <mx:Button label="Show Products" click="initMenu()"/>
    <!-- If you change the contents of the form, the next time you 
        display the Menu, it will show the updated data in the last 
        main menu item. -->
    <mx:Form>
        <mx:FormItem label="Third Submenu title">
            <mx:TextInput id="menuName" text="Clothing"/>
        </mx:FormItem>
        <mx:FormItem label="Item 1">
            <mx:TextInput id="item1" text="Sweaters"/>
        </mx:FormItem>
        <mx:FormItem label="Item 2">
            <mx:TextInput id="item2" text="Shoes"/>
        </mx:FormItem>
        <mx:FormItem label="Item 3">
            <mx:TextInput id="item3" text="Jackets"/>
        </mx:FormItem>
    </mx:Form>
</mx:Application>

Нижче приводиться SWF-файл для попереднього прикладу.

До натиснення кнопки Show Products:

Після натиснення кнопки Show Products:

Створення дескриптора даних користувача

Якщо ієрархічні дані не відповідають форматам, які підтримуються, наприклад, класом DefaultDataDescriptor, або якщо вони знаходиться в об'єкті, який не використовує дочірнє поле, — можна написати дескриптор даних користувача і конкретизувати його у властивості dataDescriptor елементу керування дерева. Дескриптор даних користувача повинен реалізувати всі методи інтерфейсу ITreeDataDescriptor.

Наступний приклад показує, як можна створити дескриптор даних користувача — в даному випадку для використання з елементом керування дерева (Tree). Цей дескриптор даних правильно керує джерелом даних, яке складається з вкладених об'єктів ArrayCollection.

Наступний код демонструє клас MyCustomTreeDataDescriptor, який реалізує тільки інтерфейс ITreeDataDescriptor. Цей клас підтримує елементи керування дерева, але не елементи керування на основі меню. Клас користувача підтримує вузли дерева, в якому дочірнє поле є або ArrayCollection, або об’єктом (Object). При отримуванні дочірніх елементів вузла повертається об'єкт, якщо дочірній об’єкт є ArrayCollection; в іншому випадку дочірній об’єкт перетворюється в ArrayCollection перед тим, як він повертається. При додаванні вузла, в залежності від типу дочірнього поля, використовується інший метод.

package myComponents
// myComponents/MyCustomTreeDataDescriptor.as
{
import mx.collections.ArrayCollection;
import mx.collections.CursorBookmark;
import mx.collections.ICollectionView;
import mx.collections.IViewCursor;
import mx.events.CollectionEvent;
import mx.events.CollectionEventKind;
import mx.controls.treeClasses.*;

public class MyCustomTreeDataDescriptor implements ITreeDataDescriptor
{

    // The getChildren method requires the node to be an Object
    // with a children field.
    // If the field contains an ArrayCollection, it returns the field
    // Otherwise, it wraps the field in an ArrayCollection.
    public function getChildren(node:Object,
        model:Object=null):ICollectionView
    {
        try
        {
            if (node is Object) {
                if(node.children is ArrayCollection){
                    return node.children;
                }else{
                    return new ArrayCollection(node.children);
                }
            }
        }
        catch (e:Error) {
            trace("[Descriptor] exception checking for getChildren");
        }
        return null;
    }

    // The isBranch method simply returns true if the node is an
    // Object with a children field.
    // It does not support empty branches, but does support null children
    // fields.
    public function isBranch(node:Object, model:Object=null):Boolean {
        try {
            if (node is Object) {
                if (node.children != null)  {
                    return true;
                }
            }
        }
        catch (e:Error) {
            trace("[Descriptor] exception checking for isBranch");
        }
        return false;
    }

    // The hasChildren method Returns true if the
    // node actually has children. 
    public function hasChildren(node:Object, model:Object=null):Boolean {
        if (node == null) 
            return false;
        var children:ICollectionView = getChildren(node, model);
        try {
            if (children.length > 0)
                return true;
        }
        catch (e:Error) {
        }
        return false;
    }
    // The getData method simply returns the node as an Object.
    public function getData(node:Object, model:Object=null):Object {
        try {
            return node;
        }
        catch (e:Error) {
        }
        return null;
    }

    // The addChildAt method does the following:
    // If the parent parameter is null or undefined, inserts
    // the child parameter as the first child of the model parameter.
    // If the parent parameter is an Object and has a children field,
    // adds the child parameter to it at the index parameter location.
    // It does not add a child to a terminal node if it does not have
    // a children field.
    public function addChildAt(parent:Object, child:Object, index:int, 
            model:Object=null):Boolean {
        var event:CollectionEvent = new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
        event.kind = CollectionEventKind.ADD;
        event.items = [child];
        event.location = index;
        if (!parent) {
            var iterator:IViewCursor = model.createCursor();
            iterator.seek(CursorBookmark.FIRST, index);
            iterator.insert(child);
        }
        else if (parent is Object) {
            if (parent.children != null) {
                if(parent.children is ArrayCollection) {
                    parent.children.addItemAt(child, index);
                    if (model){
                        model.dispatchEvent(event);
                        model.itemUpdated(parent);
                    }
                    return true;
                }
                else {
                    parent.children.splice(index, 0, child);
                    if (model)
                        model.dispatchEvent(event);
                    return true;
                }
            }
        }
        return false;
    }

    // The removeChildAt method does the following:
    // If the parent parameter is null or undefined,
    // removes the child at the specified index
    // in the model.
    // If the parent parameter is an Object and has a children field,
    // removes the child at the index parameter location in the parent.
    public function removeChildAt(parent:Object, child:Object, index:int, model:Object=null):Boolean
    {
        var event:CollectionEvent = new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
        event.kind = CollectionEventKind.REMOVE;
        event.items = [child];
        event.location = index;

        //handle top level where there is no parent
        if (!parent)
        {
            var iterator:IViewCursor = model.createCursor();
            iterator.seek(CursorBookmark.FIRST, index);
            iterator.remove();
            if (model)
                model.dispatchEvent(event);
            return true;
        }
        else if (parent is Object)
        {
            if (parent.children != undefined)
            {
                parent.children.splice(index, 1);
                if (model) 
                    model.dispatchEvent(event);
                return true;
            }
        }
        return false;
    }

}
}

Наступний приклад використовує MyCustomTreeDataDescriptor для обробки ієрархічних вкладених ArrayCollections і об'єктів. При натисненні на кнопку в дерево додається вузол шляхом виклику методу addChildAt() дескриптора даних. Зверніть увагу, що зазвичай метод addChildAt () не використовують напряму. Замість цього потрібно використовувати методи дерева або елементу керування на основі меню, які, в свою чергу, використовують методи дескриптора даних для зміни джерела даних.

<?xml version="1.0" encoding="iso-8859-1"?>
<!-- dpcontrols\CustDataDescriptor.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" creationComplete="initCollections()">

    <mx:Script>
        <![CDATA[
            import mx.collections.*;
            import mx.controls.treeClasses.*;
            import myComponents.*;
    
            /* Variables used to construct the ArrayCollection data provider
               First top-level node and its children. */
            public var nestArray1:Array = [
                {label:"item1", children: [
                    {label:"item1 child", children:     [
                        {label:"item 1 child child", data:"child data"}
                    ]}
                ]}
            ]; 
            /* Second top-level node and its children. */
            public var nestArray2:Array = [
                {label:"item2", children: [
                    {label:"item2 child", children: [
                        {label:"item 2 child child", data:"child data"}
                    ]}
                ]}
            ];
            /* Second top-level node and its children. */
            public var nestArray3:Array = [
                {label:"item3", children: [
                    {label:"item3 child", children: [
                        {label:"item 3 child child", data:"child data"}
                    ]}
                ]}
            ]; 
            /* Variable for the tree array. */
            public var treeArray:Array
            /* Variables for the three Array collections that correspond to the 
               top-level nodes. */
            public var col1:ArrayCollection;
            public var col2:ArrayCollection;
            public var col3:ArrayCollection;
            
            /* Variable for the ArrayCollection used as the Tree data provider. */
            [Bindable]
            public var ac:ArrayCollection;
            
            /* Build the ac ArrayCollection from its parts. */
            public function initCollections():void{
                /* Wrap each top-level node in an ArrayCollection. */
                col1 = new ArrayCollection(nestArray1);
                col2 = new ArrayCollection(nestArray2);
                col3 = new ArrayCollection(nestArray3);

                /* Put the three top-level node
                   ArrayCollections in the treeArray. */
                treeArray = [
                    {label:"first thing", children: col1},
                    {label:"second thing", children: col2},
                    {label:"third thing", children: col3},
                ]; 

                /* Wrap the treeArray in an ArrayCollection. */
                ac = new ArrayCollection(treeArray);
            }

            /* Adds a child node as the first child of the selected node,
               if any. The default selectedItem is null, which causes the
               data descriptor addChild method to add it as the first child
               of the ac ArrayCollection. */
            public function clickAddChildren():void {
                var newChild:Object = new Object();
                newChild.label = "New Child";
                newChild.children = new ArrayCollection();
                tree.dataDescriptor.addChildAt(tree.selectedItem, newChild, 0, ac);
            }

        ]]>
    </mx:Script>

    <mx:Tree width="200" id="tree" dataProvider="{ac}" 
        dataDescriptor="{new MyCustomTreeDataDescriptor()}"/>    
    <mx:Button label="Add Child" click="clickAddChildren()"/>
</mx:Application>

Нижче приводиться SWF-файл для попереднього прикладу:

Після натиснення кнопки Add Child:

Об’єкти даних на основі XML

Дані для дерева часто отримуються від сервера у вигляді XML, але це також може бути XML, визначений в тезі . Клас DefaultDataDescriptor може обробляти узгоджені структури даних XML.

Для визначення об’єкту XML або XMLList в MXML можна використовувати тег або . На відміну від класів XML і XMLList, в ActionScript ці теги дозволяють використовувати представлення прив’язки MXML в тесті XML, щоб вилучити вміст вузла зі змінних даних. Наприклад, можна прив'язати атрибут назви вузла до значення вводу тексту, як показано в наступному прикладі:

<mx:XMLList id="myXMLList">
    <child name="{textInput1.text}"/>
    <child name="{textInput2.text}"/>
</mx:XMLList>

Можна використовувати об’єкт XML безпосередньо як джерело даних для ієрархічного елементу керування даними. Однак, якщо об'єкт змінюється динамічно, потрібно зробити наступне:

  1. Конвертувати об’єкт XML або XMLList в об’єкт XMLListCollection.
  2. Зробити всі оновлення даних шляхом зміни об’єкту XMLListCollection.

Це гарантує те, що компонент представляє собою динамічні дані. Клас XMLListCollection підтримує використання всіх методів IList і ICollectionView інтерфейсу, і додає багато часто використовуваних методів класу XMLList. Для отримання додаткової інформації про використання XMLListCollections див. XMLListCollection objects.

Наступний приклад коду визначає два елементи керування дерева. Перший безпосередньо використовує об’єкт XML, а другий використовує об’єкт XMLListCollection як джерело даних:

<?xml version="1.0"?>
<!-- dpcontrols\UseXMLDP.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:XML id="capitals">
        <root>
            <Capitals label="U.S. State Capitals">
                <capital label="AL" value="Montgomery"/>
                <capital label="AK" value="Juneau"/>
                <capital label="AR" value="Little Rock"/>
                <capital label="AZ" value="Phoenix"/>       
            </Capitals>
            <Capitals label="Canadian Province Capitals">
                <capital label="AB" value="Edmonton"/>
                <capital label="BC" value="Victoria"/>
                <capital label="MB" value="Winnipeg"/>
                <capital label="NB" value="Fredericton"/>
            </Capitals>
        </root>
    </mx:XML>

    <!-- Create an XMLListCollection representing the Tree nodes.
         capitals.Capitals is an XMLList with both Capitals elements. -->
    <mx:XMLListCollection id="capitalColl" source="{capitals.Capitals}"/>
    
    <mx:Label text="These two Tree controls appear identical, although their data sources are different."/>

    <mx:HBox>
        <!-- When you use an XML-based data provider with a tree
             you must specify the label field, even if it
             is "label". The XML object includes the root,
             so you must set showRoot="false". Remember that
             the Tree will not, by default, reflect dynamic changes
             to the XML object. -->
        <mx:Tree id="Tree1" dataProvider="{capitals}" labelField="@label"
            showRoot="false" width="300"/> 
        
        <!-- The XMLListCollection does not include the XML root. -->
        <mx:Tree id="Tree2" dataProvider="{capitalColl}" labelField="@label" 
            width="300"/>       
    </mx:HBox>
</mx:Application>

Нижче приводиться SWF-файл для попереднього прикладу:

Цей приклад показує дві важливі властивості використання ієрархічного джерела даних з елементом керування дерева:

  • ECMAScript для об’єктів XML (E4X) повинен мати один кореневий вузол, який може не бути відповідним для відображення в дереві. Крім того, дерева можуть мати кілька елементів на самому високому рівні. Щоб запобігти відображення кореневого вузла дерева, значення властивості showRoot встановлюється в false. (Значення showRoot за замовчуванням для елементу керування дерева — це true.) Колекції XMLList, однак, не мають єдиного кореня, і як правило, немає необхідності використовувати властивість showRoot.
  • При використанні об’єктів XML, XMLList або XMLListCollection як джерела даних дерева, необхідно встановити властивість labelField, навіть якщо це «мітка» (label), якщо поле є атрибутом XML. Це потрібно зробити, тому що для позначення атрибута потрібно використовувати знак "@".

Об’єкти XMLListCollection

Об’єкти XMLListCollection забезпечують функціональність колекцій для об’єкта XMLList і роблять доступними деякі методи маніпуляцій XML для власного класу XMLList, такі як методи attributes(), children() і elements(). Більш детальну інформацію про підтримані методи див. в розділі XMLListCollection в Adobe Flex Language Reference.

Наступний простий приклад використовує об’єкт XMLListCollection як джерело даних для елементу керування списком (List control). Він використовує методи XMLListCollection для динамічного додавання елементів до джерела даних і їх видалення звідти та для його представлення у List control. Цей приклад використовує елемент керування дерева для представлення вибору пунктів покупок і List collection для представлення списку покупок.

Користувачі додають елементи до List control шляхом вибору пункту в елементі керування дерева (який використовує статичний об'єкт XML в якості джерела даних) і натиснення кнопки. Коли користувач натискає на кнопку, прослуховував події використовує метод XMListCollection для додання вибраного вузла XML до XMLListCollection. Оскільки джерело даних — це колекція, то щоб показати нові дані, List control оновлюється.

Користувачі видаляють елементи таким же чином — вибравши пункт у списку і натиснувши на кнопку видалення. Прослуховувач події використовує метод XMListCollection removeItemAt() для видалення елементу з джерела даних та його представлення в List control.

<?xml version="1.0"?>
<!-- dpcontrols\XMLListCollectionWithList.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">    
    <mx:Script>
        <![CDATA[
            import mx.collections.XMLListCollection;
            import mx.collections.ArrayCollection;
    
            /* An XML object with categorized produce. */
            [Bindable]
            public var myData:XML=
                <catalog>
                  <category name="Meat">
                      <product name="Buffalo"/>
                      <product name="T Bone Steak"/>
                      <product name="Whole Chicken"/>
                  </category>
                  <category name="Vegetables">
                      <product name="Broccoli"/>                         
                      <product name="Vine Ripened Tomatoes"/>
                      <product name="Yellow Peppers"/>
                  </category>
                  <category name="Fruit">
                      <product name="Bananas"/>
                      <product name="Grapes"/>
                      <product name="Strawberries"/>
                  </category>
              </catalog>;

            /* An XMLListCollection representing the data
               for the shopping List. */
           [Bindable]
           public var listDP:XMLListCollection = new XMLListCollection(new XMLList());
    
           /* Add the item selected in the Tree to the List XMLList data provider. */
           private function doTreeSelect():void {
               if (prodTree.selectedItem)
               listDP.addItem(prodTree.selectedItem.copy());
           }

           /* Remove the selected in the List from the XMLList data provider. */
           private function doListRemove():void {
               if (prodList.selectedItem)
                   listDP.removeItemAt(prodList.selectedIndex);
           }
        ]]>
    </mx:Script>
    
    <mx:HBox>
        <mx:Tree id="prodTree" dataProvider="{myData}" width="200"
            showRoot="false" labelField="@name"/>           
        <mx:VBox>
            <mx:Button id="treeSelect" label="Add to List"
                click="doTreeSelect()"/>
            <mx:Button id="listRemove" label="Remove from List"
                click="doListRemove()"/>
        </mx:VBox>         
        <mx:List id="prodList" dataProvider="{listDP}" width="200"
            labelField="@name"/>        
    </mx:HBox>
            
</mx:Application>

Нижче приводиться SWF-файл для попереднього прикладу:

загрузка...
Сторінки, близькі за змістом