Thanks for the reply, I think the root of the problem is the 'drilldown'
filtering while still keeping things in sync via binding.  That or I am just
not thinking about it the right way.

retrieve array from database stored in model.master ->
model.slave1, model.slave2, model.slave3 collections created from master
with preliminary filters ->
the local view variable slaveData is bound to model.slave1  <component
slaveData={model.slave1}/>  ->
slaveData in the component will get the preliminary filter of the slaveX in
the model, or if I update the user changable filter on slaveData then slaveX
will also have it's preliminary filter changed .

Thats where I'm getting stuck at, creating collections off of 1 retrieval of
data from the db, applying a filter to each collection to pre-sort them into
their category, then allowing the user to filter each category's view
further on their own actions

Is your recommendation to keep 3 master arrays in the model (manually setup
and not with a filterFunction), and when a command to update an item in 1 is
executed, I should have it update the others accordingly via looping or
setItemAt?

Sorry for the long post and my mental road block!



On 12/5/06, Alex Uhlmann <[EMAIL PROTECTED]> wrote:

   Hi Rick,

I havn't read the complete thread below, but since you're saying you're
working in a Cairngorm app, to me this looks like functionality that should
live in either one or multiple model object(s), instead of the view. The
view could just bind to a property (some collection) of that model and
update it via encapuslated API requests aka commands. Would that work for
you?

Best,
Alex

     *Alex Uhlmann *
Consultant (Rich Internet Applications)
Adobe Consulting
Westpoint, 4 Redheughs Rigg,
South Gyle, Edinburgh, EH12 9DQ, UK
p: +44 (0) 131 338 6969
m: +44 (0) 7917 428 951
[EMAIL PROTECTED]
http://weblogs.macromedia.com/auhlmann



 ------------------------------
*From:* flexcoders@yahoogroups.com [mailto:[EMAIL PROTECTED] *On
Behalf Of *Rick Schmitty
*Sent:* 05 December 2006 17:01
*To:* flexcoders@yahoogroups.com
*Subject:* Re: [flexcoders] Re: need strategy for filtering
ArrayCollections in a Cairngorm app

 To dig up an old thread... How would you go about this if you had a
component that you wanted to reuse for different views of the data
that could be filtered additionally by that view?

I've run into a similar problem Tom had where the filterFunction is
passed along or overwritten. It seems my only choice (good or bad?)
is to have all possible filtering functions in the component and pass
the component some logic on which to use for its 'base' data in
addition to any user filter applied on the already filtered 'base'
data set

Perhaps I'm going about it the wrong way. I've modified Paul's example
below:

<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml";
creationComplete="initialise()" xmlns:local="*">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.collections.ListCollectionView;
import flash.utils.Timer;

[Bindable]
public var master : ArrayCollection = new ArrayCollection();

[Bindable]
public var slave1 : ListCollectionView = new ListCollectionView(master);
[Bindable]
public var slave2 : ListCollectionView = new ListCollectionView(master);
[Bindable]
public var slave3 : ListCollectionView = new ListCollectionView(master);

public var value : int = 0;

public function initialise() : void
{
slave1.filterFunction = filterOdd;
slave1.refresh();
slave2.filterFunction = filterEven;
slave2.refresh();
slave3.filterFunction = filterDivBy10;
slave3.refresh();

var timer : Timer = new Timer( 10, 50);
timer.addEventListener( "timer", addValue);
timer.start();
}

public function addValue( event : Event ) : void
{
master.addItem( ++value );
}

public function filterOdd( item : Object ) : Boolean
{
var value : int = int(item);
return value % 2 == 1
}

public function filterEven( item : Object ) : Boolean
{
var value : int = int(item);
return value % 2 == 0
}

public function filterDivBy10( item : Object ) : Boolean
{
var value : int = int(item);
return value % 10 == 0
}
]]>
</mx:Script>

<mx:HBox width="100%">
<mx:VBox>
<mx:Label text="Master List"/>
<mx:List editable="true" dataProvider="{ master }" height="400"/>
</mx:VBox>
<local:slave slaveData="{slave1}" label="odd"/>
<local:slave slaveData="{slave2}" label="even"/>
<local:slave slaveData="{slave3}" label="divisible by 10"/>

</mx:HBox>
</mx:Application>

****** slave.mxml ******

<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml";
xmlns:ac="com. adobe.ac.util.*"
creationComplete="complete()" initialize="init()">
<mx:Script>
<![CDATA[
import mx.collections.ListCollectionView;

[Bindable]
public var slaveData:ListCollectionView;

public function filterDivBy5(item:Object):Boolean {
var value : int = int(item);
if (filterOn.selected)
return value % 5 == 0
else
return true;
}

private function init():void {
trace("init");
debug();
trace("----");
}

private function complete():void {
trace("complete");
slaveData.filterFunction=filterDivBy5;
debug();
trace("----");
}

private function filter():void {
trace("filter");
debug();
slaveData.refresh();
trace("----");
}


private function debug():void {
if (slaveData == null) {
trace("slaveData object is null");
return;
}

trace("length: "+slaveData.length);
if (slaveData.filterFunction==null)
trace("filter function: null");
else if (slaveData.filterFunction==filterDivBy5)
trace("filter function: DivBy5");
else
trace("filter function: parent filter");
}

]]>
</mx:Script>
<mx:Label id="slaveLabel" text="{this.label}"/>
<mx:List dataProvider="{slaveData}" height="400" editable="true"/>
<mx:CheckBox id="filterOn" label="Filter by Div5" change="filter()"/>
<mx:Button click="debug()"/>
</mx:VBox>

On 6/10/06, Paul Williams <[EMAIL PROTECTED] <paulw%40adobe.com>> wrote:
> Hi Tom,
>
> A nice way to do this is to create a master that is an ArrayCollection,
and then for each of your filtered lists you use a ListCollectionView. When
you create your ListCollectionView you pass your master list in as a
constructor parameter (because ArrayCollection implements Ilist). You can
then add a filter function to each of your filtered lists without affecting
the master. Each ListCollectionView will listen to the underlying IList for
changes, so these should come through immediately (if they get past the
filter!).
>
> There's a very simple demo for beta 3 below. Does this solve your
problem?
>
> Paul
>
> <?xml version="1.0" encoding="utf-8"?>
> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml";
layout="horizontal" creationComplete="initialise()">
>
> <mx:Script>
> <![CDATA[
> import mx.collections.ArrayCollection;
> import flash.utils.Timer;
>
> [Bindable]
> public var master : ArrayCollection = new ArrayCollection();
>
> [Bindable]
> public var slave1 : ListCollectionView = new ListCollectionView(master);
> [Bindable]
> public var slave2 : ListCollectionView = new ListCollectionView(master);
> [Bindable]
> public var slave3 : ListCollectionView = new ListCollectionView(master);
>
> public var value : int = 0;
>
> public function initialise() : void
> {
> slave1.filterFunction = filterOdd;
> slave1.refresh();
> slave2.filterFunction = filterEven;
> slave2.refresh();
> slave3.filterFunction = filterDivBy5;
> slave3.refresh();
>
> var timer : Timer = new Timer( 200, 50);
> timer.addEventListener( "timer", addValue);
> timer.start();
> }
>
> public function addValue( event : Event ) : void
> {
> master.addItem( ++value );
> }
>
> public function filterOdd( item : Object ) : Boolean
> {
> var value : int = int(item);
> return value % 2 == 1
> }
>
> public function filterEven( item : Object ) : Boolean
> {
> var value : int = int(item);
> return value % 2 == 0
> }
>
> public function filterDivBy5( item : Object ) : Boolean
> {
> var value : int = int(item);
> return value % 5 == 0
> }
>
> ]]>
> </mx:Script>
>
> <mx:VBox>
> <mx:Label text="Master List"/>
> <mx:List dataProvider="{ master }" height="400"/>
> </mx:VBox>
>
> <mx:VBox>
> <mx:Label id="slave1Label" text="Odd"/>
> <mx:List dataProvider="{ slave1 }" height="400"/>
> </mx:VBox>
>
> <mx:VBox>
> <mx:Label id="slave2Label" text="Even"/>
> <mx:List dataProvider="{ slave2 }" height="400"/>
> </mx:VBox>
>
> <mx:VBox>
> <mx:Label id="slave3Label" text="Divisible by 5"/>
> <mx:List dataProvider="{ slave3 }" height="400"/>
> </mx:VBox>
>
> </mx:Application>
>
> ________________________________________
> From: flexcoders@yahoogroups.com <flexcoders%40yahoogroups.com> [mailto:
flexcoders@yahoogroups.com <flexcoders%40yahoogroups.com>] On Behalf Of
Jeremy Lu
> Sent: Saturday, June 10, 2006 4:13 AM
> To: flexcoders@yahoogroups.com <flexcoders%40yahoogroups.com>
> Subject: Re: [flexcoders] Re: need strategy for filtering
ArrayCollections in a Cairngorm app
>
>
> very interesting...
>
> why not trigger a global "ArrayChangedEvent" so each fitlered
ArrayCollection can update itself according to it ? (with some binding
settings this should be feasible)
>
> the trigger point is: when new data are pushed into MasterArray,
dispatch it.
>
> Tom: if you have some sample code, I can give it a try.
>
> On 6/10/06, Tim Hoff <[EMAIL PROTECTED] <TimHoff%40aol.com>> wrote:
> I'll have to take your word on that, but I'm still skeptical. If what
you say is true, then you could still use the same approach, but instead
have the viewlisten for updates to the masterArray in the ModelLocator. You
could do this either by using the changWatcher utility or Paul Williams'
Observe tag:
> http://weblogs.macromedia.com/paulw/
> When your view hears a change to the masterArray, you would then refresh
the ArrayCollection. It's a little cumbersome, but since direct binding
doesn't want to work for you, it might be a necessary step.
> -TH
>
> --- In flexcoders@yahoogroups.com <flexcoders%40yahoogroups.com>, "Tom
Bray" <[EMAIL PROTECTED]> wrote:
> >
> > Thanks for trying. An ArrayCollection will not reflect changes made
> > directly to its source array, so new items pushed onto masterArray do
not
> > show up in my views.
> >
> > -Tom
> >
> > On 6/9/06, Tim Hoff [EMAIL PROTECTED] wrote:
> > >
> > > Changes to the masterArray in the ModelLocator should be
> > > automatically reflected in the AC if you use either of the binding
> > > methods I posted. If not, sorry. That's all I have.
> > >
> > >
> > > -TH
> > >
> > > --- In flexcoders@yahoogroups.com 
<flexcoders%40yahoogroups.com><flexcoders%40yahoogroups.com>, "Tom
> > > Bray" tombray@ wrote:
> > > >
> > > > The problem is that changes to ModelLocator.getInstance
> > > ().masterArray don't
> > > > update the views' dataProviders. In other words, the
> > > ArrayCollections that
> > > > use masterArray as their source don't know when new items are
> > > added to or
> > > > removed from masterArray. That's why I was thinking that
> > > masterArray would
> > > > actually be masterArrayCollection and I'd bind each of the view's
> > > > dataProvider ACs to it so they could stay in sync. I bound the
> > > master AC to
> > > > the sub ACs using BindingUtils and was surprised to see the filter
> > > function
> > > > on the sub ACs affect the master AC. I posted sample code here:
> > > > http://groups.yahoo.com/group/flexcoders/message/39064?l=1
> > > >
> > > > Thanks again!
> > > >
> > > > -Tom
> > > >
> > > > On 6/9/06, Tim Hoff TimHoff@ wrote:
> > > > >
> > > > >
> > > > > Something like this should do the trick:
> > > > >
> > > > > <mx:Script>
> > > > > <![CDATA[
> > > > >
> > > > > import mx.collections.ArrayCollection;
> > > > > import org.ets.main.code.model.ModelLocator;
> > > > >
> > > > > [Bindable]
> > > > > public var viewDataProvider : ArrayCollection;
> > > > > viewDataProvider=new
> > > > > ArrayCollection({ModelLocator.getInstance().masterArray});
> > > > >
> > > > > ]]>
> > > > > </mx:Script>
> > > > >
> > > > > -TH
> > > > >
> > > > >
>
> > > > > --- In flexcoders@yahoogroups.com 
<flexcoders%40yahoogroups.com><flexcoders%40yahoogroups.com><flexcoders%
>
> > > 40yahoogroups.com>, "Tom
> > > > > Bray" <tombray@> wrote:
> > > > > >
> > > > > > Thanks, Tim. That makes sense but there's one limitation I'm
> > > not sure
> > > > > how
> > > > > > to work around. That master Array of users is going to be
> > > constantly
> > > > > updated
> > > > > > by the server to show who's currenlty online. Since an Array
> > > isn't
> > > > > > bindable, how would you propagate changes from that Array to
> > > the
> > > > > filtered
> > > > > > ArrayCollections that use it as their source?
> > > > > >
> > > > > > -Tom
> > > > > >
> > > > > > On 6/9/06, Tim Hoff TimHoff@ wrote:
> > > > > > >
> > > > > > > Hey Tom,
> > > > > > >
> > > > > > > In response to this question and the BindingUtils and
> > > > > > > ArrayCollection.filter question, I offer this suggestion. In
> > > the
> > > > > > > ModelLocator maintain a single master Array of all the
> > > users. Then
> > > > > > > in each instance of your view components, create a new bound
> > > > > > > ArrayCollection (dataProvider), with the master Array as the
> > > > > > > underlying source. Each of the ArrayCollections will have a
> > > > > > > different filterFunction based on the type of view component
> > > that is
> > > > > > > instantiated. Because the ArrayCollections don't actually
> > > contain
> > > > > > > any data, just pointers to the underlying Array, I would
> > > handle the
> > > > > > > ArrayCollections and filterFunctions in viewHelpers. In a
> > > sense,
> > > > > > > you would be creating separate sub-sets of the master Array
> > > in each
> > > > > > > instance of your views. If you preferred, you could maintain
> > > each
> > > > > > > ArrayCollection (Array of ArrayCollections) in the
> > > ModelLocator as
> > > > > > > well.
> > > > > > >
> > > > > > > I hope that this makes sense,
> > > > > > > Tim Hoff
> > > > > > >
> > > > > > >
> > > > > > > --- In 
flexcoders@yahoogroups.com<flexcoders%40yahoogroups.com><flexcoders%40yahoogroups.com><flexcoders%
> > > 40yahoogroups.com ><flexcoders%40yahoogroups.com>,
> > >
> > > > >
> > > > > "Tom
> > > > > > > Bray" tombray@ wrote:
> > > > > > > >
> > > > > > > > Say my model has an ArrayCollection of all the users that
> > > are
> > > > > > > > connected to my Flex app. I then have configurable list
> > > views that
> > > > > > > > display different subsets of that collection based on
> > > different
> > > > > > > user
> > > > > > > > properties (gender, age, location, etc.). Multiple views,
> > > multiple
> > > > > > > > filters, all being fed from the same master
> > > ArrayCollection of all
> > > > > > > > connected users. I even want the user to be able to
> > > dynamically
> > > > > > > > create new views with different filters.
> > > > > > > >
> > > > > > > > Unless there's something I'm missing, each view is going
> > > to need
> > > > > > > its
> > > > > > > > very own ArrayCollection that has its own filter function
> > > set up.
> > > > > > > I'm
> > > > > > > > picturing a wrapper class that provides addFilter() and
> > > > > > > removeFilter()
> > > > > > > > methods so that the AC's filter function can traverse an
> > > array of
> > > > > > > > other filters -- kind of a CompoundCommand pattern.
> > > > > > > >
> > > > > > > > Assuming that's part of the correct approach, I want my
> > > master AC
> > > > > > > to
> > > > > > > > pump changes out to the filtering ACs which pump changes
> > > out to
> > > > > the
> > > > > > > > views. Is there a way to make the binding mechanism work
> > > for this?
> > > > > > > > Is there a simpler approach I'm overlooking?
> > > > > > > >
> > > > > > > > Any tips you can send my way would be greatly appreciated.
> > > > > > > >
> > > > > > > > Thanks,
> > > > > > > >
> > > > > > > > Tom
> > > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > > >
> > > > >
> > > >
> > >
> > >
> > >
> >
>
>
>
>
>
>
> --
> Flexcoders Mailing List
> FAQ: http://groups.yahoo.com/group/flexcoders/files/flexcodersFAQ.txt
> Search Archives:
http://www.mail-archive.com/flexcoders%40yahoogroups.com
> Yahoo! Groups Links
>
>
>
>
>

Reply via email to