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



Reply via email to