tag:robotlegs.tenderapp.com,2009-10-18:/discussions/problems/38-itemrenderer-inside-popup-window-not-mediatedRobotlegs: Discussion 2018-10-18T16:35:08Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/9154962010-01-26T19:41:01Z2010-01-26T19:42:39ZitemRenderer inside Popup window not mediated<div><p>Hi Allen.</p>
<p>I have this exact same problem - for which I tried to solve a
number of ways and I was not able to.</p>
<p>This issue actually extends passed itemRenderer's though, and it
actually affects anything on that pop-up for which you would like
to have automatically mediated.</p>
<p>I'm more than willing to sit down and try and solve this. I
ended up giving up due to time constraints at work. I ended up
putting all the logic that I needed inside my itemRenderer.
Thankfully I did not have to inject anything into it and I relied
solely on the itemRenderer's data property to retrieve the
information I needed. I just made sure the objects within the
dataprovider included this information.</p>
<p>I doubt this post will help you much but it is a link to the
issue I posted about this.</p>
<p><a href=
"http://knowledge.robotlegs.org/discussions/problems/35-mediation-of-components-contained-within-a-flex-popup">
http://knowledge.robotlegs.org/discussions/problems/35-mediation-of...</a></p>
<p>Lets solve this sucker. I think if there was an eloquent way to
circumvent this issue that RobotLegs would have an answer for any
and all flex solutions.</p>
<p>-Levi</p></div>levi.stropetag:robotlegs.tenderapp.com,2009-10-18:Comment/9154962010-01-26T19:48:53Z2010-01-26T19:48:57ZitemRenderer inside Popup window not mediated<div><p>Ok... I came up with this solution, and it works just fine.. its
just too much of a hack... but at leat it was quick and painless,
and and it works</p>
<p>So I created a new new Event</p>
<pre>
<code>public class MediatorEvent extends Event
{
public static const REGISTER:String = 'mediatorRegister';
public var view:Object;
public function MediatorEvent(type:String, view:Object, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
this.view = view;
}
public override function clone():Event
{
return new MediatorEvent(type, view, bubbles, cancelable);
}</code>
</pre>
<p>and the from the actual MXML custom itemRenderer</p>
<p><code>creationComplete="dispatchEvent(new
MediatorEvent(MediatorEvent.REGISTER, this, true))"</code></p>
<p>and then in the CustomPopUpWindowMediator</p>
<pre>
<code> public override function onRegister():void
{
view.list.dataProvider = model.collection;
view.addEventListener(MediatorEvent.REGISTER, register);
}
private function register(e:MediatorEvent):void
{
mediatorMap.createMediator(e.view);
}</code>
</pre>
<p>Its quite a workaround, but it works just as expected... and
only took under 5 minutes to figure out.</p>
<p>Would be cool if it just worked like it does with itemRenderers
that ARE NOT inside pop-up windows.</p>
<p>Hope this helps others with the same issue.</p>
<p>Allen</p></div>Allentag:robotlegs.tenderapp.com,2009-10-18:Comment/9154962010-01-26T19:53:02Z2010-01-26T19:53:03ZitemRenderer inside Popup window not mediated<div><p>Hi Levi...</p>
<p>Thanks for your post. It was actually your post that sorta gave
me the idea.. then I quickly tried it... and it worked! So I rushed
back here to post it.</p>
<p>Its not THE solution... as it requires an extra step... buts at
least its quite simplistic.. and best of all.. works like a
charm!!!</p></div>Allentag:robotlegs.tenderapp.com,2009-10-18:Comment/9154962010-01-26T19:56:45Z2010-01-26T19:56:45ZitemRenderer inside Popup window not mediated<div><p>I will note that I due to the complexities of itemRenderer's
that that issue specifically will be a hard one to solve, unless we
were able to have some sort of injectionListener that listened
specifically on the popup's display list.</p>
<p>I do wonder how you are able to mediate the pop-up automatically
as your view. I had to do the following. I did this inside of a
"DisplayformCommand".</p>
<pre>
<code> var distroForm:DistributionAccountForm = new DistributionAccountForm();
distroForm.x = Application.application.width / 2 - distroForm.width / 2;
distroForm.y = 75;
model.removeThisWindow = distroForm; //for removal using PopUpManager.removePopUp(model.removeThisWindow)
PopUpManager.addPopUp(distroForm, contextView, true, PopUpManagerChildList.POPUP);
// mediator class is automatically chosen from mediatorMap definition in the application context
// but we still have to create it since the popup view component is not on the main displayList
mediatorMap.createMediator(distroForm);</code>
</pre></div>levi.stropetag:robotlegs.tenderapp.com,2009-10-18:Comment/9154962010-01-26T20:01:26Z2010-01-26T20:07:27ZitemRenderer inside Popup window not mediated<div><p>I just saw your reply - you posted it while I was following
up.</p>
<p>I tried to do something like that but I was unsuccessful -
however you got further than me. I think had some error in my logic
flow somewhere.</p>
<p>Where do you map your mediator to the itemRenderer? I'm assuming
you have a mediator for the popUp and you are doing it there?</p>
<p>I'm curious now - when you remove this pop up from the display
list, does it get GC'd? I assumed that if I was able to reliably
mediate the mediators, what would happen should the list need
refreshed based on dataBinding? Flex tries to re-use itemRenderers,
and GC's some and apparently is kinda random. I'm just wondering
how nice this plays in the event that, your dataprovider for the
list goes from 10 records down to say, 2.<br></p>
<p>What happens to the 8 mediators and itemRenderers that were
there before? I'm curious to know if this causes a memory leak due
to the specialness of the pop up being on a different display
list.</p>
<p>Thoughts?<br></p></div>levi.stropetag:robotlegs.tenderapp.com,2009-10-18:Comment/9154962010-01-26T20:04:21Z2010-01-26T20:04:21ZitemRenderer inside Popup window not mediated<div><p>Levi's solution, to manage the state of item renderers via their
data property, is 100% the proper approach. Mediating Flex 3 item
renderers is bad on so many levels. Item renderers should be
considered private (or at least internal to their owner), with no
app layer access to them what-so-ever or you are just asking for
pain. This is true irrespective of framework.</p></div>Joel Hookstag:robotlegs.tenderapp.com,2009-10-18:Comment/9154962010-01-26T20:04:56Z2010-01-26T20:05:48ZitemRenderer inside Popup window not mediated<div><p>I do just like you that in a command... I create the new view
object and then just do...</p>
<p><code>PopUpManager.addPopUp(distroForm, contextView,
false);</code></p>
<p>And that's it... the view gets auto-mediated after that..
period.</p>
<p>I tried it and it just worked the first time, say 2 or 3 weeks
ago on another project I was working on.</p>
<p>Try just taking out that last line, see if it works... then just
trace('I got mediated!') in the mediator's onRegister() see if it
works</p></div>Allentag:robotlegs.tenderapp.com,2009-10-18:Comment/9154962010-01-26T20:18:32Z2010-01-26T20:18:35ZitemRenderer inside Popup window not mediated<div><p>@levi Well the pop-up I just re-use through the life of the
app.. I have a WindowCommand that handles that. It just gets
created once, then from there on its the same window instance.<br>
As far at the IR's... no, I am not handling GC nor removing the
mediators. Its true that those remaining 8 will still be in memory
even though not used, but that really depends on your app. It may
be the case that 10 seconds later those 8 have to be re-used, and
thats how I imagine Flex 3 IR's where made for.</p>
<p>@Joel I think Joel is right on. I read on another post you wrote
that the events should be dispatched from the IR and caught at the
pop-up window's mediator. Thats the way I would have gone too,
keeping the IR's private.<br>
But in my case, these IR's have 3 comboboxes that need to be
populated from data on the model, based on what the user selects.
So thats why I figured mediating them was the easiest approach.</p></div>Allentag:robotlegs.tenderapp.com,2009-10-18:Comment/9154962010-01-26T20:21:48Z2010-01-26T20:21:48ZitemRenderer inside Popup window not mediated<div><p>I'd consider structuring the VOs that populate the data model
differently. If you need new VOs that carry the appropriate data,
that is a much better way to approach it. Add the necessary
collections as properties of the VOs to use as combo box data
providers. There is no issue leveraging Flex's binding capabilities
in your VOs within item renderers. It is much better than exposing
the renderers, in my opinion (and experience).</p>
<p>Easy/convenient is a slippery slope at time ;)</p></div>Joel Hookstag:robotlegs.tenderapp.com,2009-10-18:Comment/9154962010-01-26T20:30:01Z2010-01-26T20:30:05ZitemRenderer inside Popup window not mediated<div><p>Hey Joel,</p>
<p>That is an interesting. Certainly keeps things at the data/model
level without having to control the data on the IR's based on their
mediator.</p>
<p>I think my main impulse to go with mediating the IR's is because
depending on user input, I need to...</p>
<p><code>view.cb1.selectedIndex = -1;</code></p>
<p>In order to get the prompt property visible again on the
combox.</p>
<p>If I can could control that from the VO, then its a winner.</p></div>Allentag:robotlegs.tenderapp.com,2009-10-18:Comment/9154962010-01-26T20:34:38Z2010-01-26T20:34:38ZitemRenderer inside Popup window not mediated<div><p>Yes Unfortunately Joel's suggestion seems to be the only clean
way to do it.</p>
<p>If you want to test your view/itemRenderer though I think it's
kinda tough. But if you were to test the data going in, then you
can rely on integration tests to exercise the view.</p>
<p>I do like your solution though, I wouldn't call it a hack so
much as calling it what works. Thank you for posting it - I'm
definitely putting it in my RL toolbox.</p></div>levi.stropetag:robotlegs.tenderapp.com,2009-10-18:Comment/9154962010-01-26T20:49:12Z2010-01-26T20:50:13ZitemRenderer inside Popup window not mediated<div><p>Just for clarification... I was wrong about that not needing to
call the createMediator() method. I made a mistake. I had put that
in a WindowCommand and totally forgot how it even worked, and
somehow today I looked at that Article and thought, I didnt have to
do that... So sorry about misleading you on that Levi.</p>
<p>here is my WindowCommand, which was made with making one
single-instance windows</p>
<pre>
<code>public class WindowCommand extends Command
{
private static var windows:Dictionary = new Dictionary();
private static var opened:Array = new Array();
[Inject] public var event:BaseWindowEvent;
public function WindowCommand()
{
super();
}
public override function execute():void
{
var center:Boolean;
var window:BaseWindow;
switch (event.type)
{
case BaseWindowEvent.CLOSE:
PopUpManager.removePopUp(event.window);
opened.splice(opened.indexOf(event.window), 1);
break;
case BaseWindowEvent.OPEN:
window = windows[event.klass] as BaseWindow;
if (window == null)
{
window = windows[event.klass] = new event.klass();
mediatorMap.createMediator(window);
center = true;
}
if (opened.indexOf(window) === -1)
{
opened.push(window);
PopUpManager.addPopUp(window, contextView, window.modal);
if (center)
PopUpManager.centerPopUp(window);
}
else
{
PopUpManager.bringToFront(window);
}
if (event.data)
window.data = event.data;
window.show();
break;
}
}
}</code>
</pre>
<p>And here is the BaseWindowEvent</p>
<pre>
<code>public class BaseWindowEvent extends Event
{
public static const CLOSE:String = 'windowClose';
public static const OPEN:String = 'windowOpen';
public static const SAVE:String = 'windowSave';
public var window:BaseWindow;
public var klass:Class;
public var data:Object;
public function BaseWindowEvent(type:String, window:BaseWindow=null, klass:Class=null, data:Object=null, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
this.window = window;
this.klass = klass;
this.data = data;
}
public override function clone():Event
{
return new BaseWindowEvent(type, window, klass, data, bubbles, cancelable);
}
}</code>
</pre>
<p>The BaseWindow is just an MXML base to base of my window views.
Sorry about my erroneous comment again on this matter.</p></div>Allen