Hi, In your post you wrote: > They are not really meant to create a new collection > that you can then add items to.
Actually, while you are correct on the one hand that they [collection views] are not meant to create a new collection, one of the design centers for views was meant to allow manipulating the view and transparently updating the underlying list. This means that you can add items to the view which may or may not appear in that view but will definitely update the underlying list and potentially show up in other views operating against the same list. I will get a bug logged against the SDK for this. Thanks, jw --- In flexcoders@yahoogroups.com, "dwischusen" <[EMAIL PROTECTED]> wrote: > > Hi Giff, > > > I agree that this probably a bug, in that the addItemAt() method call > should either produce the expected behavior or throw an error, but I > do think that you are trying to use Filters for something other than > what they were intended for. > > Filters are suppose to allow you "use a filter function limit the > ICollection view to a subset of the data provider source." So they > allow you to filter data, view the data, and then reset to the values > in the source. They are not really meant to create a new collection > that you can then add items to. > > When you use a sort or a filter, the collection stores the values in > an array called localIndex. When there is data in this array (i.e., > localIndex != null), any component that is reading from this > collection will read from the localIndex, not the source. In this > situation, when you try to add an item to collection you are trying to > add it to the localIndex, which is not really allowed. If you look at > the docs for localIndex (see below) you will see that it should not > contain anything that is not in the source. > > localIndex property > > protected var localIndex:Array > When the view is sorted or filtered the localIndex property contains > an array of items in the sorted or filtered (ordered, reduced) view, > in the sorted ordder. The ListCollectionView class uses this property > to access the items in the view. The localIndex property should never > contain anything that is not in the source, but may not have > everything in the source. This property is null when there is no sort. > > So, if you want to filter and then add items to the results you shoul > store the results of the filter in a new collection and then add the > items to that collection, or you could use a temporary collection to > do the filtering for you and the return the results back to your > original collection (see below FilterAC() below). > > Derek > > <?xml version="1.0"?> > <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" width="600"> > <mx:Script> > <![CDATA[ > import mx.collections.*; > > // Function to filter out all items with labels that are > not in the > // range of M-N. > public function stateFilterFunc(item:Object):Boolean { > return item.label >= "M" && item.label < "Q"; > } > > // Function to apply the filter function the ICollectionView. > public function filterAC():void { > var tempAC : ArrayCollection = new > ArrayCollection(myAC.source); > tempAC.filterFunction=stateFilterFunc; > //Refresh the collection view to apply the filter. > tempAC.refresh(); > myAC.source = tempAC.toArray(); > } > > // Function to Reset the view to its original state. > public function resetAC():void { > myAC.filterFunction=null; > //Refresh the collection view. > myAC.refresh(); > } > > public function addItem():void { > myAC.addItemAt({label:'PA', data: 'Harrisburg'}, 0); > } > > ]]> > </mx:Script> > > <!-- An ArrayCollection with an array of objects. --> > <mx:ArrayCollection id="myAC"> > <mx:Array id="myArray"> > <mx:Object label="LA" data="Baton Rouge"/> > <mx:Object label="NH" data="Concord"/> > <mx:Object label="TX" data="Austin"/> > <mx:Object label="MA" data="Boston"/> > <mx:Object label="AZ" data="Phoenix"/> > <mx:Object label="OR" data="Salem"/> > <mx:Object label="FL" data="Tallahassee"/> > <mx:Object label="MN" data="Saint Paul"/> > <mx:Object label="NY" data="Albany"/> > </mx:Array> > </mx:ArrayCollection> > > <!-- Buttons to filter, sort, or reset the view in the second ComboBox > control. --> > <mx:HBox width="100%"> > <mx:Button id="filterButton" label="Filter" click="filterAC ();"/> > <mx:Button id="resetButton" label="Reset" click="resetAC ();"/> > <mx:Button id="addButton" label="Add Item" click="addItem ();"/> > </mx:HBox> > <mx:HBox width="100%"> > <!-- A ComboBox populated by the underlying Array object. > This control shows that Array retains its original order. --> > <mx:ComboBox id="cb2" rowCount="10" dataProvider="{myArray}"/> > <!-- A ComboBox populated by the collection view of the Array. --> > <mx:ComboBox id="cb1" rowCount="10" dataProvider="{myAC}"/> > </mx:HBox> > > </mx:Application> > > --- In flexcoders@yahoogroups.com, "thegiffman" <thegiffman@> wrote: > > > > Hi Folks - I have a serious bug here. I was wondering if there is a > > good workaround or if this has been documented. > > > > Basically, it seems that if you add a filter function to an > > ArrayCollection, any future changes to the collection are tacked on to > > the end, until you explicitly call the refresh() function. This is a > > rather serious problem, because data bindings do not wait for refresh > > calls! > > > > For instance, if I have an AC of objects, and I add another object to > > the beginning of that AC, the object will normally be put at the > > beginning. However, if I have added a filter and called the refresh() > > function at least once, this item gets added to the END of the array. > > > > To make matters worse, if you have an AC of bindable objects, this > > even holds for items that are edited. Say I have an AC of a simple > > bindable Class with a "name" property. If I then do something like: > > > > myArrayCollection[3].name = myArrayCollection[3].name + "!"; > > > > The third item will be pulled out of its spot, and tacked onto the > > end! This is a serious problem if an AC is bound to a TileList or > > similar display component. This means that, for any item that is > > updated, the entire list is going to be redrawn, and redrawn wrongly! > > If I am super careful to put refresh() calls after every property > > change, things seem to fix themselves. But this horribly subverts the > > MVC architecture and the entire purpose of DataBindings. Indeed, the > > DataBindings are now responsible for creating extra overhead doing > > things that aren't wanted. > > > > Any help on this would be most appreciated. > > > > Giff Ransom > > Emergent Game Technologies > > > > > > > > P. S. - here is an example to see the bug. > > > > 1) paste the following code into a new application > > 2) run the program > > 3) click "Load Folder into List" (numbers 1-6 will appear) > > 4) click "Append Item" (item will appear at the END of list) > > 5) comment out line 18 ( items.refresh(); ) > > 6) repeat steps 2-4 (item will appear at the BEGINNING of list) > > > > > > > > <?xml version="1.0" encoding="utf-8"?> > > <mx:Application > > xmlns:mx="http://www.adobe.com/2006/mxml" > > creationComplete="init()"> > > > > <mx:Script> > > <![CDATA[ > > import mx.collections.ArrayCollection; > > > > [Bindable] > > public var items:ArrayCollection = new ArrayCollection([]); > > > > // Init functions > > > > public function init():void > > { > > items.filterFunction = filterFunction; > > items.refresh(); > > addEventListener (Event.ENTER_FRAME,handleEnterFrame); > > } > > > > public function filterFunction (obj:Object):Boolean {return true;} > > > > public function handleEnterFrame (event:Event):void > > { > > var str:String = ""; > > > > for(var i:int = 0;i<items.length;i++){ > > str += items[i].name + ". " + "\n"; > > } > > > > textArea.text = str; > > } > > > > // Button Handlers > > > > public function loadList():void > > { > > items.removeAll(); > > > > for(var i:int=0;i<6;i++){ > > var obj:* = {}; > > obj.name = i; > > items.addItem(obj); > > } > > } > > > > > > > > public function addItem():void > > { > > var item:* = {}; > > item.name = 666; > > items.addItemAt(item,0); > > } > > > > public function changeList():void > > { > > var item:* = items[int(Math.random() *6)]; > > > > item.name = item.name + "!"; > > } > > > > ]]> > > </mx:Script> > > > > <mx:VBox> > > <mx:HBox> > > <mx:Button x="830" y="118" label="Load Folder into List" > > click="loadList()"/> > > <mx:Button x="830" y="118" label="Append Item" click="addItem()"/> > > <mx:Button x="830" y="118" label="Change the List" > > click="changeList()"/> > > </mx:HBox> > > > > <mx:TextArea id="textArea" width = "550" height="300"/> > > </mx:VBox> > > > > </mx:Application> > > >