Hi Lachlan,

 Sorry I couldn't get back to you sooner - its been a zoo here.  Thanks to
Matt, I've removed 1 set of problems (can't initialize [Bindable]'s during
declaration).  I think I've narrowed down what my remaining problem is, its
related to my no 'SHOW' event problem I posted about a while back.

 Basically, it appears that in nested containers, 'SHOW' and 'HIDE' are not
fired for every component or even every container.  The show/hide
fires on the outermost container only.  for instance, with the code below:

 When you 'tab' between 'component 1' and 'component 2', neither Canvas A
or B generates show Events
 When you switch between 'Canvas A' and 'Canvas B', neither 'embedded view'
generates show Events

I can understand this for performance reasons - it cuts down on the number
of events to be processed. However, it makes it hard for me to develop
'components' that don't have to be aware of their containment structure.  I
end up having to hard-code calls to 'showMe()' and 'hideMe()' in the parent
container(s).

I tried having the component listen for 'SHOW' events on its parent
container, but it can get very difficult to determine _what_ container you
should be listening to.  For instance, should emedded component 1 listen for
'SHOW' on Canvas A, or Component 2?  I've had instances where it should be
either or both!

Are there some patterns for developing reusable components like this, that
can be dropped anywhere? I'd like to just be able to add the component, give
it a dataProvider, and let it run.  Having to 'tweak' its display from the
parent container just seems wrong.  The component should be able to maintain
its own view state without outside help.

Steve

Code Follows:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"; width="400"
height="400" >
<mx:Script>
 <![CDATA[
   import flash.events.Event;
   public function H1(e:Event):void { trace("Component1 SHOW fired"); }
   public function H2(e:Event):void { trace("Component2 SHOW fired"); }
   public function H3(e:Event):void { trace("Canvas A SHOW fired"); }
   public function H4(e:Event):void { trace("Canvas B SHOW fired"); }
   public function H5(e:Event):void { trace("Embedded View Component 1 SHOW
fired"); }
   public function H6(e:Event):void { trace("Embedded View Component 2 SHOW
fired"); }
 ]]>
</mx:Script>
<mx:TabNavigator width="100%" height="100%">
  <mx:Canvas label="Component 1" show="H1(event)"><mx:Label text="Component
1" /></mx:Canvas>
  <mx:Canvas label="Component 2" show="H2(event)">
     <mx:LinkBar dataProvider="{foo}" />
      <mx:ViewStack id="foo" top="25">
         <mx:Canvas label="Canvas A" show="H3(event)">
           <mx:Label text="Component2 Canvas A" />
           <mx:Canvas top="25" show="H5(event)">
              <mx:Label text="Embedded View Component 1" />
           </mx:Canvas>
         </mx:Canvas>
         <mx:Canvas label="Canvas B" show="H4(event)">
           <mx:Label text="Component2 Canvas B" />
           <mx:Canvas top="25" show="H6(event)">
              <mx:Label text="Embedded View Component 2" />
           </mx:Canvas>
         </mx:Canvas>
      </mx:ViewStack>
  </mx:Canvas>
</mx:TabNavigator>
</mx:Application>


On 12/8/06, Lachlan Cotter <[EMAIL PROTECTED]> wrote:

  Hi Steve,

Is your problem to do with your rules about which view to display? If it's
getting a bit complicated or 'crufty', then you probably need another level
of abstraction. Encapsulate your rules about which view should be displayed
inside a getter called currentView. Bind your view stack to this.

Now you need to work out how that variable gets updated when appropriate.
One way is to make this a bindable property with a custom event type. Now
dispatch that event type when the length of dataProvider changes. Obviously,
your getter method for currentView has to contain the logic you described
for deciding which view to use.

Is that what you were looking for?

Cheers,
Lach




On 06/12/2006, at 5:27 AM, Steve Hindle wrote:

Hi All,

I'm trying to create a component to use as an example or 'template'
of how to achieve a record list and detail view in flex. I'm starting
with a simple 'contact' record (model) that has name, address, phone,
email, etc. The list of records is held in _dataProvider, and the
specific record to be displayed in the detail view is held in _model.
My goal is to have a nice clean skeleton of how to handle this sort of
display.

My component is a viewstack with 2 views:
View 0: a datagrid displaying summary info of a list of records
(title, first, last). Double click on an entry should
open it in the
'detail' view. dataProvider is bound to _dataProvider, an
arrayCollection.
View 1: a custom component that displays all my model fields.
It has a 'model' property that is used to set the
record to be displayed.
model is a single static instance of my record type, and
all fields in the
view are bound to it ( eg text='{_model.last_name}' )

The logic for the component is pretty simple:
1. Initial view is determined by _dataProvider.length
2. if _dataProvider.length = 1, default to 'detail' view of that record
3. if _dataProvider.length > 2, default to 'list' view
4. if _dataProvider.length = 0, add a new empty record and
default to 'detail'
view to allow data entry.

This mostly works - however, I run into 'odd' problems with
dataBinding and Initialization, etc. As my script gets cruftier with
all sorts of special case logic, and
manually poking stuff to get dataBindings updated, I wonder if perhaps
others have a better Design Pattern or template for this ??

I'd appreciate any feedback...


Reply via email to