tag:robotlegs.tenderapp.com,2009-10-18:/discussions/problems/479-opening-and-closing-a-popup-from-commandsRobotlegs: Discussion 2012-03-08T09:20:23Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/136778432012-02-14T09:55:12Z2012-02-14T09:55:12Zopening and closing a popup from commands<div><p>see answer from:<a href=
"http://knowledge.robotlegs.org/discussions/questions/817-using-a-callout-with-a-list">http://knowledge.robotlegs.org/discussions/questions/817-using-a-ca...</a></p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/136778432012-02-14T09:56:47Z2012-02-14T09:56:47Zopening and closing a popup from commands<div><p>I'd REALLY recommend against doing this in a command.<br>
It's view logic so it should be handled by the view tier.<br>
I'd create a separate view/mediator pair that is responsible for
showing and hiding the popup.</p>
<p>And to answer your question, views aren't permanently registered
with the system, they're registered temporarily when the view is
added to the display list and the corresponding mediator is being
created in order to potentially inject the view reference into the
mediator. Right after that the view is unregistered again. This is
for two reasons:<br>
1/ if having multiple instances of the same view onstage how would
the injector know which view instance it needs to inject into the
command?<br>
2/ it enforces the separation of concerns between the tiers</p></div>creynderstag:robotlegs.tenderapp.com,2009-10-18:Comment/136778432012-02-14T12:55:45Z2012-02-14T12:55:45Zopening and closing a popup from commands<div><p>@ creynders The problem with pop-ups is that you have to
manually create and unmap their Mediators.<br>
I agree with you, that opening and closing pop-ups should be View
logic, and, in general, that manipulating views in commands is not
a good practice.</p>
<blockquote>
<p>I'd create a separate view/mediator pair that is responsible for
showing and hiding the popup.</p>
</blockquote>
<p>Let’s say you have an OpenPopUpButton that would trigger
the opening of a pop-up.<br>
You could mediate this OpenPopUpButton and let its mediator create
a mediator for the popup.<br>
So, you could place the OpenPopUpButton in every view that needs
such functionality, and, indeed, you wouldn’t need a command
in this case.</p>
<p>But, what if you want to open or close a pop-up due to other
user interactions (selectedItem, tool tip, navigating to another
view) or some conditions in your code?<br>
Which view/mediator pair would you use? It should be the
view/mediator pair that triggered the opening of the popup, right?
But what would you do if you needed the same pop-up in different
views? You’d certainly want to avoid having the same code in
different mediators.</p>
<p>Dispatching SomePopUpEvent.OPEN_POPUP or
SomePopUpEvent.CLOSE_POPUP, whenever you need to open or close a
popup, is all you’d have to do if you’d use commands,
and changes to the code would be made in just one place.</p>
<p>It’s not nice to use commands, but I think it’s an
acceptable compromise in the case of popups or similar components
(in rl v1). I’d also like to avoid using a command, if
possible, but I gave up trying to find another way of managing
popups with rl 1.<br>
It would be really, really great, if you could share with us a
better solution!! Something using the SystemManager? A PopUpManager
utility, maybe? :)</p>
<blockquote>
<p>And to answer your question, views aren't permanently registered
with the system, they're registered temporarily when the view
is<br>
added to the display list and the corresponding mediator is
being<br>
created in order to potentially inject the view reference into
the<br>
mediator. Right after that the view is unregistered again.</p>
</blockquote>
<p>As I understood the question, Corey is talking about popups or
callout containers(mobile), which behave like popups.</p>
<p><a href=
"http://knowledge.robotlegs.org/kb/reference-mvcs-implementation/how-to-mediate-a-flex-popup">
How to Mediate a Flex Popup</a>:<br>
"The problem is that Flex creates the popup "outside" of the
context view's display list. Robotlegs has no way to automatically
mediate the view component. When using PopUpManger to create
popups, it is necessary to manually create the mediator for the
view component"</p>
<p>I’d really like to see a good solution for handling popups
in rl v1 :)</p>
<p>Cheers,<br>
Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/136778432012-02-14T15:26:34Z2012-02-14T15:26:34Zopening and closing a popup from commands<div><p>The trick is to pass Application.application.systemManager as
the contextView instead of Main.mxml, then popups are automatically
mediated.<br>
See <a href=
"http://knowledge.robotlegs.org/discussions/solutions/4-mediation-of-popups-in-flex">
http://knowledge.robotlegs.org/discussions/solutions/4-mediation-of...</a></p>
<p>But come to think of it, and looking at the date when I wrote
this, this was probably still using Flex 3, and I'm not sure
whether it still works in Flex 4.x<br>
I'd have to look into that.</p>
<p>But even if it does work in Flex 4.x, you still can't use a
command to close the popup due to the limitations I wrote in my
previous post.</p></div>creynderstag:robotlegs.tenderapp.com,2009-10-18:Comment/136778432012-02-14T18:19:14Z2012-02-14T18:19:14Zopening and closing a popup from commands<div><blockquote>
<p>The trick is to pass Application.application.systemManager as
the contextView instead of Main.mxml, then popups are automatically
mediated. See <a href=
"http://knowledge.robotlegs.org/discussions/solutions/4-mediation-of">
http://knowledge.robotlegs.org/discussions/solutions/4-mediation-of</a>...</p>
</blockquote>
<p>Yes, I know about it from your post, but I’ve never tried
it out.</p>
<blockquote>
<p>But even if it does work in Flex 4.x, you still can't use a
command to close the popup due to the limitations I wrote in my
previous post.</p>
</blockquote>
<p>Well, there is a way to do that in case of multiple instances of
a modal popup opened in the same view, but I admit it’s not
the best way. If it’s not a modal popup, there is always just
one instance open.<br>
For multiple instances:<br>
Every time the opening command is mapping a popup, it generates an
id for the popup view and it adds it to an array in a Model.<br>
The id is used in injector.mapValue() to get an instance of a popup
and create its mediator.</p>
<p>Then in the closing command, the triggering event has a payload
with popups’ id, that is then passed to
injector.getInstance()’s named:String, and it can close this
instance of a popup.<br>
If you need to close all popups, you can iterate the model’s
array and close each instance.<br>
Something like that :)</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/136778432012-02-14T18:29:58Z2012-02-14T18:29:58Zopening and closing a popup from commands<div><p>I actually did try using the systemManager but was getting
errors and stuff wasn't working correctly.</p>
<p>If I do go the route where I close the popup from a mediator
will injection happen or do I need to use the getinstance
method?</p>
<p>Also curious what the RL 2.0 version changes regarding popups
and this kind of situation.</p></div>coreytag:robotlegs.tenderapp.com,2009-10-18:Comment/136778432012-02-15T08:12:58Z2012-02-15T08:12:58Zopening and closing a popup from commands<div><blockquote>
<p>I actually did try using the systemManager but was getting
errors and stuff wasn't working correctly.</p>
</blockquote>
<p>Yeah, it could be it works differently in flex 4.x (I assume
you're using flex 4.x?)<br>
Ondina's work-around using commands should definitely be a possible
solution.</p></div>creynderstag:robotlegs.tenderapp.com,2009-10-18:Comment/136778432012-02-15T11:07:35Z2012-02-15T11:07:35Zopening and closing a popup from commands<div><blockquote>
<p>If I do go the route where I close the popup from a mediator
will injection happen or do I need to use the getinstance
method?</p>
</blockquote>
<p>I don’t know what you mean, so I’ll use my example
from the other thread:<br>
In SomeView(mediated by SomeMediator ) clicking on a button
triggered the opening of SomeCalloutView (Callout container). If
you meant injecting or getting an instance of SomeCalloutView in
SomeMediator in order to close it and remove SomeCallOutMediator, I
would say that would indeed be a bad practice and would really
defeat the purpose of a Mediator :) SomeMediator shouldn’t
know about or manage any views other than its own (SomeView).<br>
So, if you want to use mediators for closing a popup and removing
its mediator you can do it like so:</p>
<p><strong>A</strong> In case of closing the callout through a
button in the callout view:</p>
<p>1.Simple SomeCalloutView (Callout container without any other
mediated views inside) + SomeCallOutMediator</p>
<p>SomeCalloutView:</p>
<pre>
<code>
protected function onClosePopUp(event:MouseEvent):void
{
dispatchEvent(new SomePopUpEvent(SomePopUpEvent.CLOSE_POPUP));
this.close();
}</code>
</pre>
<p>SomeCallOutMediator:</p>
<pre>
<code>
protected function onClosePopup(event:SomePopUpEvent):void
{
mediatorMap.removeMediator(this);
}</code>
</pre>
<p>2.SomeCalloutView(Callout container) contains CalloutNavigator
(ViewNavigator) which contains AnotherView(View)</p>
<p>SomeCalloutView:</p>
<pre>
<code>
protected function onClosePopUp(event:MouseEvent):void
{
dispatchEvent(new SomePopUpEvent(SomePopUpEvent.CLOSE_POPUP));
this.close();
}</code>
</pre>
<p>SomeCallOutMediator:</p>
<pre>
<code>
protected function onClosePopup(event:SomePopUpEvent):void
{
mediatorMap.removeMediator(this);
dispatch(new SomePopUpEvent(SomePopUpEvent.CLOSE_POPUP));
}</code>
</pre>
<p>CalloutNavigatorMediator and AnotherMediator listen for it and
do: mediatorMap.removeMediator(this);</p>
<p><strong>B</strong> In case of closing the callout from elsewhere
(say from SomeView->SomeMediator):</p>
<p>SomeCallOutMediator, CalloutNavigatorMediator and every other
interested mediator would listen for SomePopUpEvent.CLOSE_POPUP
(re)dispatched by SomeMediator .</p>
<p>SomeCallOutMediator:</p>
<pre>
<code>
protected function onClosePopup(event:SomePopUpEvent):void
{
mediatorMap.removeMediator(this);
view.close();
}</code>
</pre>
<br>
And the other mediators:
<pre>
<code>
protected function onClosePopup(event:SomePopUpEvent):void
{
mediatorMap.removeMediator(this);
}</code>
</pre>
<p>The difference between the 2 cases:<br>
A- SomeCalloutView closes itself<br>
B- SomeCallOutMediator closes SomeCalloutView</p>
<p>In a previous post, I gave you an example of closing popups in a
command because that’s what you’ve asked :)</p>
<p>In the next days or so, as time permits, I will add different
ways of handling the opening and closing of a callout to the code
on github, which was actually just a quick change to an older
example in response to your question from the other thread. And
later, when rl2 will be mature enough, I’ll make an rl2
version as well.</p>
<p>Did I answer your questions?<br>
Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/136778432012-02-18T09:38:30Z2012-02-18T09:38:30Zopening and closing a popup from commands<div><p>Just wanted to confirm that using SystemManager, as creynders
suggested, works with Flex 4.6.0.</p>
<p>ContextView.mxml</p>
<p>Instead of:<br>
context=new ApplicationContext(this);<br>
you have to do this:<br>
context=new ApplicationContext(this.parent);</p>
<p>where this.parent is [object
ContextView_mx_managers_SystemManager]</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/136778432012-02-19T17:53:55Z2012-02-19T17:53:55Zopening and closing a popup from commands<div><p>thanks for the reply.</p>
<p>Here is what I have done.</p>
<ol>
<li>Created an open popup command that creates the mediator.</li>
<li>In the popup window view mediator I add a listener and then
close the window.</li>
</ol>
<pre>
public class BusyPopUpMediator extends Mediator
{
[Inject] public var view:BusyPopUp;
public function BusyPopUpMediator()
{
super();
}
public override function onRegister():void{
addContextListener(BusyPopupEvent.CLOSE, onClose);
}
private function onClose(event:BusyPopupEvent):void{
view.close();
this.mediatorMap.removeMediator(this);
}
}
</pre>
<p>This achieves the same result as using a command to close the
window but is much clearer and follows best practices.</p>
<p>Now the one problem I came across is that the popup will
sometimes not close because the BusyPopupEvent.CLOSE event is sent
before the listener is set up. This only happens with my Test
client which generates the data locally instead of using REST
calls. Any suggestions?</p></div>coreytag:robotlegs.tenderapp.com,2009-10-18:Comment/136778432012-02-20T11:01:33Z2012-02-20T11:11:49Zopening and closing a popup from commands<div><p>Some general thoughts about the startup process in a rl v.1-flex
app, and why the order of code's execution matters: (from a
<a href="https://github.com/downloads/Ondina/robotlegs-incremental/robotlegs_incremental_slides.pdf">
presentation</a> , that's still WIP, due to lack of time)</p>
<p>A Flex application built with Robotlegs is considered to be
ready to consume external services and to respond to user input<br>
-when the Flex application has completed its startup process<br>
AND<br>
-when the framework has completed its wiring process, that is, when
the classes extending the MVC framework have been<br>
• mapped<br>
• instantiated<br>
• supplied with their dependencies<br>
• registered</p>
<p>If you want, you can take a look at some diagrams illustrating
this process:</p>
<p><a href=
"https://github.com/Ondina/robotlegs-incremental/raw/97354bfdcc649ef9078ea5e2f349e5ef88736ada/robotlegs-incremental-resources/images/reduced_step_00.png">
Figure 1</a></p>
<p><a href=
"https://github.com/Ondina/robotlegs-incremental/raw/97354bfdcc649ef9078ea5e2f349e5ef88736ada/robotlegs-incremental-resources/images/reduced_step_01.png">
Figure 2</a></p>
<p><a href=
"https://github.com/Ondina/robotlegs-incremental/raw/97354bfdcc649ef9078ea5e2f349e5ef88736ada/robotlegs-incremental-resources/images/reduced_step_02.png">
Figure 3</a></p>
<p><a href=
"https://github.com/Ondina/robotlegs-incremental/raw/97354bfdcc649ef9078ea5e2f349e5ef88736ada/robotlegs-incremental-resources/images/reduced_step_03.png">
Figure 4</a></p>
<p><a href=
"https://github.com/Ondina/robotlegs-incremental/raw/97354bfdcc649ef9078ea5e2f349e5ef88736ada/robotlegs-incremental-resources/images/reduced_step_04.png">
Figure 5</a></p>
<p>The creation of Mediators, whose purpose is to mediate the
communication between Views and other application tiers, depends on
the ADDED_TO_STAGE event, which is dispatched by the
Mediators’ Views (Flex components) and listened to by the
Robotlegs internal classes: the Context and the MediatorMap.</p>
<p>When will a Mediator receive data from a Service?<br>
When it can listen to custom events dispatched by the Service after
accessing the external resources.<br>
When can a Mediator listen to custom events?<br>
After it has been created.<br>
When is the Mediator created?<br>
After its View has been added to the display list, because the
Robotlegs internal classes will create a Mediator first after its
View has dispatched an ADDED_TO_STAGE event.<br>
When is a View added to stage?<br>
After the Application container has been added to the display
list.</p>
<p>But, as you already know by now, Flex creates a popup "outside"
of the context view's display list, and you have to create its
Mediator manually. That means, popup’s Mediator won’t
be ready for communication with other parts of the app before its
creation.<br>
Therefore you’d have to make a service call **after** the
popup's Mediator has been created and it has added a listener for
the event it is supposed to listen for!</p></div>Ondina D.F.