0

我有一个源集合(现在是一个简单的数组)。在运行时,我使用与源相同的数组创建 ArrayCollections(每个集合显示相同的源,但它们的过滤方式不同)。我的问题是,当将新项目添加到源时,如果更新了该新项目的属性之一,则已创建的数组集合不会更新。

有人对此有解决方案吗?如果我的来源是字典怎么办。如何从源字典创建不同的 ArrayCollections,而每当添加新项目或更新项目时集合都会更新?

谢谢

4

3 回答 3

2

问题是数组不在[Bindable]Flex 中。所以你有几个选择:

  • 制作source一个 ArrayCollection,并为CollectionEvent.COLLECTION_CHANGE.
  • 以某种方法将项目添加到所有数组集合中,addItemToCollections以使它们保持同步。

这是我所描述的一个例子:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
    xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:local="*"
    creationComplete="creationCompleteHandler()">

    <mx:Script>
        <![CDATA[
            import mx.events.CollectionEvent;
            import mx.events.CollectionEventKind;
            import mx.collections.ArrayCollection;
            import ColorPalette;

            protected function creationCompleteHandler():void
            {
                var item:Object;
                var i:int = 0;
                var n:int = source.length;
                for (i; i < n; i++)
                {
                    item = source[i];
                    collectionA.addItem(item);
                    collectionB.addItem(item);
                    collectionC.addItem(item);
                    bindableCollection.addItem(item);
                }
                bindableCollection.addEventListener(CollectionEvent.COLLECTION_CHANGE, collectionChangeHandler);
            }

            protected function collectionChangeHandler(event:CollectionEvent):void
            {
                switch (event.kind)
                {
                    case CollectionEventKind.ADD :
                        collectionA.addItem(event.items[0]);
                        collectionB.addItem(event.items[0]);
                        collectionC.addItem(event.items[0]);
                    break;
                }
            }

            public function addItem():void
            {
                source.push({name:"new item " + (Math.random()*1000).toString()});
            }

            public function addItemToCollection():void
            {
                var item:Object = {name:"new item " + (Math.round(Math.random()*1000)).toString()};
                collectionA.addItem(item);
                collectionB.addItem(item);
                collectionC.addItem(item);
            }

            public function addToBindableCollection():void
            {
                var item:Object = {name:"new item " + (Math.round(Math.random()*1000)).toString()};
                bindableCollection.addItem(item);
            }

        ]]>
    </mx:Script>

    <mx:Array id="source">
        <mx:Object name="one"/>
        <mx:Object name="two"/>
        <mx:Object name="three"/>
    </mx:Array>

    <mx:ArrayCollection id="collectionA"/>
    <mx:ArrayCollection id="collectionB"/>
    <mx:ArrayCollection id="collectionC"/>
    <mx:ArrayCollection id="bindableCollection"/>

    <!-- sample lists -->
    <mx:Panel id="panel" width="100%" height="100%">
        <mx:Button label="Add Item to Source" click="addItem()"/>
        <mx:Button label="Add Item to Collections" click="addItemToCollection()"/>
        <mx:Button label="Add Item to Bindable Collection" click="addToBindableCollection()"/>
        <mx:HBox width="100%" height="100%">
            <mx:List id="listA" dataProvider="{collectionA}" labelField="name"/>
            <mx:List id="listB" dataProvider="{collectionB}" labelField="name"/>
            <mx:List id="listC" dataProvider="{collectionC}" labelField="name"/>
        </mx:HBox>
    </mx:Panel>

</mx:Application>

让我知道这是否有帮助,兰斯

于 2010-02-19T23:13:40.240 回答
0

我的解决方案是:我创建了一个从 ArrayCollection 派生的新类。将其命名为 SourceCollection。添加了一个新的私有成员,它是 Dictionary,创建时将weakKeys 设置为 true。一个新的公共函数从其元素创建一个新的 ArrayCollection,并将这个创建的集合的引用添加到私有字典中,例如:

public function createCollection():ArrayCollection
{
   var result:ArrayCollection = new ArrayCollection();
       result.addAll(this);
   createdCollections[result] = null;
   return result;
}

重写了 addItemAt、removeItemAt 和 removeAll 函数:每个函数都调用其超级函数并遍历字典,并执行相应的函数。注意 addItem 和 addAll 也调用 addItemAt,所以不需要覆盖它们。一个例子是:

override public function addItemAt(item:Object, index:int):void
{
   super.addItemAt(item, index);

   for (var coll:Object in createdCollections)
   {
     (coll as ArrayCollection).addItemAt(item, index);
   }
}

还添加了一个迭代字典并计算项目的测试函数。如果我动态创建列表并使用 createCollection 函数分配从源创建的 ArrayCollection,添加、删除反映良好,所有的源项目都具有我想要的相同源项目,并且在删除动态创建的列表后,一段时间后,跟踪列表计数会自动减少。

如果您将对象放在在任何更改时调度 propertyChange 事件的源中,所有列表也会显示更改。

于 2010-02-20T13:44:04.277 回答
0

我相信您将需要使用ObjectUtil.copy()并复制您的数组。

于 2010-02-19T22:23:27.263 回答