What is the best way to implement multiple flex components?


I'm developing a Flex/AIR application that's growing big, and some of the components need to be seen from different points of view (i.e Admin, Staff, User, Guest). I've seen myself placing code in those components to handle what the user can and can't see. But it's becoming unmanageable as the code and the roles grow bigger. I was wondering what's the best way to implement multiple views inside the components while keeping them as reusable as possible.

What I'm doing right now:

<mx:HBox width="100%" horizontalAlign="right" visible="{_view == TS_VIEW || _view == PRJ_VIEW}"
       includeInLayout="{_view == TS_VIEW || _view == PRJ_VIEW}">
<mx:Button label="Agregar" click="button1_clickHandler(event)"
           enabled="{_state != ADDING_STATE &amp;&amp; !_loading &amp;&amp; _canAdd}"/>

Is there any better way to do this, also applies for the states as you can see I'm doing almost the same thing with them.

Thanks to all of your for your answers!

EDIT - I'm using Flex 3.5 and will be migrating to Flex 4.

I've encountered some similar issues in a large codebase I've assumed responsibility for, and I've been working toward two major goals:

  • Make the views as small as is reasonable, and reuse them via composition
  • Break apart view-specific code and back-end functionality (data processing, server-side requests,etc.)

Reusable Views

When building a view which is a superset of another (possibly, Admins and Users) I've been trying to build separate views which are comprised of similar components. An Admin view might "wrap" a User view and add whatever functionality it needs. When this works (which isn't always), it means I don't have to handle too many states because one view is simply a wrapper around another.

When wrapping doesn't work, I try to find common pieces of functionality to build each view separately.

For example: Admins and Users might have login controls, but not Guests. These would be a separate MXML component which I would then include in the Admin and User views. Other controls common to all 3 might be another MXML component which would be included in all 3 views. This technique is a little more work, and you need to be careful not to go crazy (e.g. winding up with one MXML file per Flex container/control), but it means I can reuse certain visual components without copying and pasting the. It also means each view can customize how they display them, if need be.

I've used inheritance in my views, but only when they clearly had an IS-A relationship and changing the code in one would necessitate a change in the other. I've also used states to control smaller changes in a single view, but I try to keep them restricted to one or two states so it doesn't, as you mentioned, get terribly unwieldy.

Decoupled Functionality

I used presenters to help decouple the view's connection to its data. Each view has a presenter object which it binds to for its data. This keeps the SCRIPT tag in the view very small since the view only needs to know what data in the presenter to bind and what methods to call when its controls are invoked.

These presenters may also be shared between views.

Here's an example of how this might look in a User/Admin login project:

| User View      |        -----------------------       ---------------
|   Login Button |------- | Presenter           |       | Model/      |
------------------        | Login Click Handler |-------| Controller/ |
                          -----------------------       | ...         |
                                   |                    ---------------
------------------                 |
| Admin View     |                 |
|   Login Button |------------------

The User and Admin views are fairly simple: they're an assemblage of visual controls (HBoxes, Sliders, Buttons, whatever), written in MXML with as little ActionScript code as I can manage (though they usually have some). Each one is given a presenter object (written in ActionScript and injected by a framework), which has bindable properties/data and functions which the view can invoke. The presenters are also, in some way, able to relay the changes to the properties/data to the backend of the application (e.g. via controllers, events, etc.). They relay any updates to the data back to the view, via their bindable properties/data.

To facilitate this, I've been using Parsley, though there are a number of other frameworks which will also help with this type of decoupling.

This makes creating new views fairly easy, since the back-end functionality is mostly written. If it's not written, I write a new presenter specific to the view I'm creating, or try to reuse an existing one via inheritance or composition.

I think this will make it a little easier to migrate to Flex 4 (something I'm pushing our project to do very soon): all the major view-related changes should be restricted to MXML files, and the presenters should change very little. I won't be chasing down visual components which need to change anywhere but in the view.

Here are two good articles which discuss breaking down views as well: