Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Over 10 years of community discussion and knowledge are maintained here as a read-only archive.

New discussions should be taken up in issues on the appropriate projects at https://github.com/PureMVC

Pages: [1]
Print
Author Topic: View composed of view  (Read 12383 times)
thomasvst
Courseware Beta
Jr. Member
***
Posts: 10


View Profile Email
« on: October 10, 2007, 01:22:02 »

Hello,

I've an application composed of a 'main' view that display a login form at startup (this 'main' view has a mediator). Once the user is successfully identified, others views are dynamically added (function of user permissions) in the 'main view'.

Here is the code of the main view :
:
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox
horizontalAlign="center"
verticalAlign="middle"
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:login="org.sampleapps.flex.elibrary.view.login.*">

<mx:Script>
<![CDATA[
import org.sampleapps.flex.elibrary.model.vo.User;

/* ----- Constants ----- */

internal static const STATE_USER_NOT_IDENTIFIED : String = '';
internal static const STATE_USER_IDENTIFIED : String = 'STATE_USER_IDENTIFIED';

/* ----- Properties ----- */

[Bindable]
public var user : User;

]]>
</mx:Script>

<login:LoginView id="loginView"/>

<mx:states>
<mx:State name="STATE_USER_IDENTIFIED">
<!-- Remove the login panel -->
<mx:RemoveChild target="{loginView}"/>
<!-- Add a menu and the main content -->
<mx:AddChild position="lastChild">
<mx:VBox width="100%" height="100%">
<mx:ApplicationControlBar width="100%">
<mx:ToggleButtonBar height="100%"
dataProvider="{viewStack}" id="toggleButtonBar" />
<mx:Spacer width="100%"/>
<mx:Text text="Connected as {user.firstName} {user.lastName}"/>
</mx:ApplicationControlBar>
<mx:ViewStack width="100%" height="100%" creationPolicy="all" id="viewStack" />
</mx:VBox>
</mx:AddChild>
</mx:State>
</mx:states>

</mx:VBox>

Here are my questions :
  • whom should create the mediator of the loginView ? the startup command (that already create the mediator of the main view) or the mainViewMediator ?
  • whom should add and create the views and the mediators that will be added in the viewStack ?

Thank you.
« Last Edit: October 10, 2007, 01:39:15 by thomasvst » Logged
thomasvst
Courseware Beta
Jr. Member
***
Posts: 10


View Profile Email
« Reply #1 on: October 10, 2007, 05:57:25 »

Correct me if I'm wrong :

The mainViewMediator is in fact the Application's Mediator. So it handle the creation of the remaining Mediators (the loginViewMediator in my case and the dynamically added views' mediators).
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #2 on: October 10, 2007, 09:39:54 »

In order to handle deferred instantiation properly we must be able to have Mediators that are created dynamically at runtime and after the StartupCommand or similar has run.

So an ApplicationMediator may listen to an Application which has a Viewstack whose children will only be created when navigated to. When they are created, the ViewStack sends an Event that makes it back to the ApplicationMediator. There are 2 ways to go about that:

If you create a custom Event, you can just pass the reference to the new child and its ordinal inside the ViewStack on the Event. The app creates appopriate Mediator, passing the reference to the new child.

Or you can expose a reference to the child and its ordinal as part of the Application's API to its Mediator. Then have the app send a normal Event that the ApplicationMediator hears, grabs the reference and ordinal of the newly created child from the Application and creates the appropriate Mediator for that component.

-=Cliff>
Logged
jinglesthula
Newbie
*
Posts: 8


View Profile Email
« Reply #3 on: May 22, 2008, 02:41:18 »

Question about Flex states:

When Flex changes states there is much adding and removing of children.  Depending on the complexity of the view components you may have as many or almost as many mediators as there are view components.

When the components are added and removed I'm sure that events are fired that can be listened to and that on these events the appropriate mediator(s) can instantiate and register (on add) or unregister and dispose of (on remove) mediators for these view components.

My question is (1) where and (2) when to add the event listeners? 

What about nested components?  Example: my application has a state that adds a custom component, which itself has multiple states and may itself contain custom components with their own states and nested components.  Depending on the complexity of the application, this nesting of stateful components may be arbitrarily deep.

Cliff, am I right in thinking that you are suggesting that the Application has a single Viewstack that fires a specific even any time any view component is added to it and that the ApplicationMediator can listen to this event and responds appropriately (either by setting up the corresponding mediator(s) or passing on that task and a reference to the newly added view component to a command)?  That would make sense, but my questions then would be what is the event name, how do I reference the view components as they are added, and if that reference is something like lastChildAdded will the framework have time to respond by executing the code to grab the reference before the next view component is added to the Viewstack (I'm assuming that event handler functions execute when a creationComplete or childAdded event or the like fires before the runtime continues on to add the next view component as the application or component changes view state).

Thanks for the great framework and being so helpful in the forums.
Logged
lapluviosilla
Newbie
*
Posts: 1


View Profile Email
« Reply #4 on: May 28, 2008, 10:13:49 »

I have some questions of my own, but I think I can answer your question about obtaining the component reference. I recommend you create a custom event to hold a reference to the newly created component. Perhaps have the component pass in a reference to itself on it's creationComplete event.

:
creationComplete="dispatchEvent(new ComponentLoadedEvent(ComponentLoadedEvent.COMPLETE, this));"
ComponentLoadedEvent is your custom event and the second parameter is a reference to itself (the view component).

My question is the same as yours, where should the event listeners be added and handled? I think the most obvious answer is to have each components "parent" handle the load event and register the mediator, but this will not work. Let me try to explain. Let's assume component A is some child component buried deep inside the view hierachy (many layers below the application), and component B is a child component of A. If we register the event listener for component B in component A's mediator and if A's mediator was registered after A's creationComplete event by some parent mediator, then component B's component loaded handler won't be called. This is because A's mediator constructor will be called after A's creationComplete and creationComplete means that all of A's sub-components are "complete" as well. Therefore B's loaded handler never get's called because B's component loaded event will have already been dispatched by the time the listener is registered!!

Does this mean all the component loaded events should bubble up and that we should handle all of them in the ApplicationMediator; whether it handles it internally or uses a command? Or maybe the listeners need to be registered in the "initialize" event instead of the creationComplete event? If we use the initialize event to register mediators then we come back to the same problem where we can't use the mediator's constructor properly.

We need to depend on loading events for all components and can't assume that we only have to use it for viewstacks and similar components. Flex is very unpredictable and occasionally just decides to get out of sync with respect to loading components.  :D

Thanks Cliff for all your great help!! There are many forums out there with great support, but this is the first I've seen where the actual project creator is really dedicated to the community. It's a blessing to all of us that are just starting to learn the flex architecture, even for those of us who have many years of experience in architecting large webapps in other languages.  ;)
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #5 on: May 29, 2008, 06:48:35 »

If the components are actually instantiated when Flex fires creation complete on the app then jus have an application mediator break off the pieces and hand wrap mediators around them.

Only in the case of deferred instantiation do you need to be listening for creationComplete on a component.

You can at that time have the parent of the component that was created tell its mediator by letting the event bubble or by dispatching a different event.

-=Cliff>
Logged
Pages: [1]
Print