更新运行时创建的数组集合,它们都有相同的源

发布于 2024-08-22 09:47:20 字数 231 浏览 9 评论 0原文

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

有人有解决这个问题的办法吗? 如果我的来源是字典怎么办?如何从源字典创建不同的 ArrayCollections,而集合会在添加新项目或更新项目时更新?

谢谢

I have a source collection (now a simple Array). At run-time I create ArrayCollections using the same array as the source (each collection show the same source, but they are differently filtered). My problem is, when a new item added to the source, the already created arraycollections wont updated if one of the property of this new item is updated.

Anyone has a solution to this?
What if my source is a Dictionary. How to create different ArrayCollections from the source dictionary, while the collections update whenever new item added, or an item is updated?

thanx

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

紫﹏色ふ单纯 2024-08-29 09:47:20

问题是数组在 Flex 中不是[Bindable]。因此,您有几个选择:

  • 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>

如果有帮助,请告诉我,

The issue is that arrays aren't [Bindable] in Flex. So you have a few options:

  • Make source an ArrayCollection, and addEventListener for CollectionEvent.COLLECTION_CHANGE.
  • Add items to all array collections in some method addItemToCollections to keep them all in sync.

Here is an example of what I am describing:

<?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>

Let me know if that helps,
Lance

金橙橙 2024-08-29 09:47:20

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

I believe you will need to use ObjectUtil.copy() and make copies of your Array.

娇柔作态 2024-08-29 09:47:20

我的解决方案是:
我创建了一个从 ArrayCollection 派生的新类。将其命名为 SourceCollection。
添加了一个新的私有成员,它是一个字典,是使用 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 事件的源中,则所有列表也会显示更改。

My solution is:
Ive created a new class derived from ArrayCollection. Name it SourceCollection.
Added a new private member that is a Dictionary, created with weakKeys turned to true.
A new public function creates a new ArrayCollection from its elements, and add the reference of this created collection to the private dictionary like:

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

Overrided the addItemAt, removeItemAt and removeAll function: each calls its super function and iterates through the dictionary, and do the appropriate function. Note addItem and addAll also calls addItemAt, so dont need to override them.
One example is:

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);
   }
}

Also added a test function that iterates through the dictionary, and count the items.
If i dynamically creates Lists and assign ArrayCollection created from source with createCollection function, adding, removeing reflected fine, all has the same source items, that i wanted, and after removing dynamically created lists, after a while, tracked list count decreases automatically.

If you put objects in the source that dispatches propertyChange event on any change, all Lists shows the change, too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文