我有一个源集合(现在是一个简单的数组)。在运行时,我使用与源相同的数组创建 ArrayCollections(每个集合显示相同的源,但它们的过滤方式不同)。我的问题是,当将新项目添加到源时,如果更新了该新项目的属性之一,则已创建的数组集合不会更新。
有人对此有解决方案吗?如果我的来源是字典怎么办。如何从源字典创建不同的 ArrayCollections,而每当添加新项目或更新项目时集合都会更新?
谢谢
我有一个源集合(现在是一个简单的数组)。在运行时,我使用与源相同的数组创建 ArrayCollections(每个集合显示相同的源,但它们的过滤方式不同)。我的问题是,当将新项目添加到源时,如果更新了该新项目的属性之一,则已创建的数组集合不会更新。
有人对此有解决方案吗?如果我的来源是字典怎么办。如何从源字典创建不同的 ArrayCollections,而每当添加新项目或更新项目时集合都会更新?
谢谢
问题是数组不在[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>
让我知道这是否有帮助,兰斯
我的解决方案是:我创建了一个从 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 事件的源中,所有列表也会显示更改。
我相信您将需要使用ObjectUtil.copy()并复制您的数组。