tag:robotlegs.tenderapp.com,2009-10-18:/discussions/robotlegs-2/24246-modularityRobotlegs: Discussion 2018-10-18T16:35:59Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/424473352017-04-28T12:11:49Z2017-04-28T12:11:49ZModularity<div><p>Hi Oleg,</p>
<p>If you take a look at the StageObserverExtension, you can see that there is a single instance of the StageObserver being used throughout the life cycle of an application:</p>
<p>"The Stage Observer Extension adds a single instance. Which listens for everything that is Event.ADDED_TO_STAGE on all root containers in the Container Registry, and then processes the view for you."</p>
<p><strong>StageObserverExtension</strong></p>
<p><a href="https://github.com/robotlegs/robotlegs-framework/blob/master/src/robotlegs/bender/extensions/viewManager/StageObserverExtension.md#stage-observer-extension">https://github.com/robotlegs/robotlegs-framework/blob/master/src/ro...</a></p>
<p><a href="https://github.com/robotlegs/robotlegs-framework/blob/master/src/robotlegs/bender/extensions/viewManager/StageObserverExtension.as#L63">https://github.com/robotlegs/robotlegs-framework/blob/master/src/ro...</a></p>
<p>StageObserver:<br>
<a href="https://github.com/robotlegs/robotlegs-framework/blob/master/src/robotlegs/bender/extensions/viewManager/impl/StageObserver.as">https://github.com/robotlegs/robotlegs-framework/blob/master/src/ro...</a></p>
<p>Now, take a look at the <strong>ModularityExtension</strong>:</p>
<p><a href="https://github.com/robotlegs/robotlegs-framework/tree/master/src/robotlegs/bender/extensions/modularity#extension-installation">https://github.com/robotlegs/robotlegs-framework/tree/master/src/ro...</a></p>
<p>The first parameter, <strong>inherit</strong>: Should this context inherit dependencies from a parent context?</p>
<p>Usually, when you want to add a view, say SimpleView to ContextView1 and also another instance of SimpleView to ContextView2, and they should have different mediators, you need to create 2 mappings:</p>
<p>One in you ContextView1 - config:</p>
<p>mediatorMap.map(SimpleView).toMediator(SimpleMediator);</p>
<p>And another in your ContextView2 -config :</p>
<p>mediatorMap.map(SimpleView).toMediator(SimpleMediator);</p>
<p>You set "inherit" to false when you install the ModularityExtension in your child context:</p>
<p>.install(new ModularityExtension(false, false))</p>
<p>And now, each context will handle SimpleView through the correspondingly mapped mediator.</p>
<p>You said:" I use StageObserverExtension and I do need it ".<br>
Does that mean that you can't use a mapping like in my example above?</p>
<p>I hope that helps. Let me know if it doesn't, and provide more details about how you are using the StageObserver.</p>
<p>Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/424473352017-04-29T11:08:01Z2017-04-29T11:11:31ZModularity<div><p>Hi Ondina, thank you so much for helping me!<br>
Yes I use mapping like in your example and the problem is that StageObserver listens to ContextView1 ADDED_TO_STAGE events in capture phase<br>
<a href="https://github.com/robotlegs/robotlegs-framework/blob/master/src/robotlegs/bender/extensions/viewManager/impl/StageObserver.as#L83">https://github.com/robotlegs/robotlegs-framework/blob/master/src/ro...</a><br>
, so all ADDED_TO_STAGE events of ContextView2 children will also be handled as ContextView2 is parent of ContextView1. So then SimpleView added to ContextView2 will be handled by Context1 StageObserver. Looks like the only work-around here is to listen to ContextView2 ADDED_TO_STAGE event in capture phase with higher priority and call stopPropagation() in case ContextView2.contains(event.target) .<br>
I tried Modularity with false,false but It haven't helped. As I understand this extension is only responsible for sharing injector between contexts.</p></div>oleg3000tag:robotlegs.tenderapp.com,2009-10-18:Comment/424473352017-04-29T17:20:34Z2017-04-29T17:20:34ZModularity<div><p>You're welcome, Oleg!</p>
<blockquote>
<p>So then SimpleView added to ContextView2 will be handled by Context1 StageObserver.</p>
</blockquote>
<p>There is <strong>only one</strong> StageObserver! So, yes, SimpleView will be handled by the same StageObserver, in Context1 and in Context2. But you shouldn't be concerned about the internal working of the framework as long as you are configuring your contexts correctly.</p>
<p>Do I understand you correctly that you are using the StageObserver directly in your code to manage your views? If so, why do you need to do that?</p>
<blockquote>
<p>As I understand this extension is only responsible for sharing injector between contexts.</p>
</blockquote>
<p>...and mappings, and/or create child-injectors and mappings</p>
<p>"The ModularityExtension allows a context to inherit dependencies from a parent context, and/or expose its dependencies to child contexts."</p>
<p>dependencies==mappings</p>
<blockquote>
<p>I tried Modularity with false,false but It haven't helped.</p>
</blockquote>
<p>That works for sure. Without seeing your code I can't say why it doesn't work for you. Would it be possible to show your configs and mappings for the 2 contexts or to attach a simple example illustrating your use case?</p>
<p>Could it be that you are using the same MVCBundle for both contexts?</p>
<p>You can see an example of using the ModularityExtension with different settings:</p>
<p><a href="http://knowledge.robotlegs.org/discussions/robotlegs-2/6915-best-practice-for-sharing-mappings-between-contexts#comment_29170824">http://knowledge.robotlegs.org/discussions/robotlegs-2/6915-best-pr...</a></p>
<p>At the end of the answer there is an attachment that you can download. (ondina-robotlegs-bender-shared-configs ) It is an air application.</p>
<p>And at the end of this message you'll find an example based on the one above, but having just one child context.</p>
<p>You can add SimpleView to the RootContextView<br>
You can add a ChildContextView to the RootContextView<br>
You can add SimpleView to ChildContextView</p>
<p>SimpleMediator is mapped to SimpleView, first inside of RootRobotlegsContext -> MediatorsConfig</p>
<p>and then inside of ChildRobotlegsContext -> ChildContextMediatorsConfig</p>
<p>ChildRobotlegsContext uses a custom MVCSBundle: MVCSBundleTwo where ModularityExtension(false, false)</p>
<p>Look at the traces inside of SimpleMediator and see how each SimpleView is communicating only with the mapped mediator.</p>
<p>Just in case you need to know more about modularity and inter-modular communication:</p>
<p><a href="https://github.com/Ondina/robotlegs-bender-modular-air">https://github.com/Ondina/robotlegs-bender-modular-air</a></p>
<p><a href="https://github.com/Ondina/robotlegs-bender-as3-modular-example">https://github.com/Ondina/robotlegs-bender-as3-modular-example</a></p>
<p>Let me know how it goes.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/424473352017-05-02T06:28:09Z2017-05-02T14:58:49ZModularity<div><blockquote>
<p>Do I understand you correctly that you are using the StageObserver directly in your code to manage your views? If so, why do you need to do that?</p>
</blockquote>
<p>I use StageObserverExtension</p>
<blockquote>
<p>Could it be that you are using the same MVCBundle for both contexts?</p>
</blockquote>
<p>Different MVCSBundles, but same mediator-view mapping</p>
<blockquote>
<p>Would it be possible to show your configs and mappings for the 2 contexts or to attach a simple example illustrating your use case?</p>
</blockquote>
<p>Sure, I've changed your example a little <a href="https://www.sendspace.com/file/7x1gvv">https://www.sendspace.com/file/7x1gvv</a></p></div>oleg3000tag:robotlegs.tenderapp.com,2009-10-18:Comment/424473352017-05-02T15:00:52Z2017-05-02T15:00:52ZModularity<div><blockquote>
<p>I use StageObserverExtension</p>
</blockquote>
<p>Yeah, but the only purpose of StageObserverExtension is to instantiate StageObserver <strong>once</strong>.</p>
<p>I still don't understand how you use the extension, because the modified example that you've attached is just adding a simple child-context to the root-context.<br>
Also, I don't understand why you need to map SomeView in the root-context <em>and</em> in the child-context. If you don't want the root-context to react to SomeView being added to the stage, you don't create a mapping for it in the root-context.<br>
If you could explain your use case, as in what you want to achieve by having 2 mappings, I might be able to help you. Otherwise I'll just keep guessing different scenarios ;)</p>
<p>In the example I've attached to my previous answer (ondina_simple_child_context) there is a SimpleView added to the root-context and another SimpleView added to the child-context. Each instance has its own mediator.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/424473352017-05-02T15:41:28Z2017-05-02T15:41:30ZModularity<div><blockquote>
<p>Also, I don't understand why you need to map SomeView in the root-context and in the child-context. If you don't want the root-context to react to SomeView being added to the stage, you don't create a mapping for it in the root-context.</p>
</blockquote>
<p>Will try to explain<br>
The project1 contains from A,B,C Views. I want to have a (lets call it widget) widget1 which is actually a copy of project1, but it contains C View only. What do I want is to be able to add that widget1 into the project1 (as a child in view tree), thats why I have same CMediator-CView mappings(I assume contexts are isolated so I define the mapping for both contexts).<br>
In the example I sent I added <code>mediatorMap.map(SomeView).toMediator(SomeMediator);</code><br>
mapping to the shell's MediatorConfig, so both child and parent context has got that mapping. When you try to add SomeView to child context - you'll see in logs that SomeMediator is initialized 2 times, so I want to completely isolate child context from the parent one.<br>
In other words, roughly, I'd like to add a copy of Application inside itself, that's why I want to be able to isolate these contexts.</p></div>oleg3000tag:robotlegs.tenderapp.com,2009-10-18:Comment/424473352017-05-02T16:52:43Z2017-05-02T16:52:43ZModularity<div><blockquote>
<p>When you try to add SomeView to child context - you'll see in logs that SomeMediator is initialized 2 times, so I want to completely isolate child context from the parent one.</p>
</blockquote>
<p>In the modified example that you added you <strong>did not</strong> add SomeView to child context.<br>
SomeView <strong>IS</strong> the view used to build the child context!!!<br>
Each context has a VIEW: the root context (ShellMainView) and the child context (SomeView)</p>
<p>Did you take a look at the example I attached to this discussion? The zip file at the end of my second answer to you?? It's called ondina_simple_child_context .zip<br>
There you can see exactly what you're describing. SimpleView is something like your CView, it can be added to the root-context and to the child-context, as well.<br>
In my example, RootContextView is adding a ChildContextView and a SimpleView. ChildContextView is also adding a SimpleView. The 2 SimpleViews are "isolated" from each other. The SimpleView has a mapping for the root and another for the child context.</p>
<p>Take a look at the example and let me know why is not a good solution for you.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/424473352017-05-11T11:18:30Z2017-05-11T14:24:14ZModularity<div><p>Hi Ondina,<br>
I've checked your example - it actually doesn't create second context, as group1_creationCompleteHandler seems to be never called.</p>
<p>I have changed your example a bit to show how to reproduce the issue, what did I do:</p>
<ul>
<li>
<p>Added creationComplete listener to trigger group1_creationCompleteHandler</p>
</li>
<li>
<p>Added missing interface implementation " implements IConfig" to ChildContextMediatorsConfig and added this config into ChildRobotlegsContext</p>
</li>
<li>
<p>Added .initialize() call to both contexts</p>
</li>
</ul>
<p>After that you'll se 2 SimpleMediator.initialize() calls in log</p></div>oleg3000tag:robotlegs.tenderapp.com,2009-10-18:Comment/424473352017-05-11T14:25:59Z2017-05-11T14:26:01ZModularity<div><p>Changed example in attachment:</p></div>oleg3000tag:robotlegs.tenderapp.com,2009-10-18:Comment/424473352017-05-12T11:10:59Z2017-05-12T11:10:59ZModularity<div><p>Hi Oleg,</p>
<p>First of all, I can't download your modified example. The zip file seems to be corrupted.</p>
<p>You are right, I made a mistake. I forgot to add the FlexEvent.CREATION_COMPLETE inside of the ChildContextView and the ChildContextMediatorsConfig implements IConfig thing! It probably happened because I first changed my original example (robotlegs-bender-shared-configs) to illustrate the simple_child_context case, but then I decided to create a new project just for that matter. I was in a hurry when I copied and pasted configurations from one project into another and some things got lost on the way...;)</p>
<p>Sorry for that and thanks for the corrections you've made.</p>
<blockquote>
<p>Added .initialize() call to both contexts</p>
</blockquote>
<p>That's not needed!!</p>
<p>The contexts will be initialized just fine, because they both have a context view.</p>
<p>See here:<br>
<a href="https://github.com/robotlegs/robotlegs-framework#context-initialization">https://github.com/robotlegs/robotlegs-framework#context-initializa...</a></p>
<p>So, is now everything working as you want it to work? Is your initial problem solved?</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/424473352017-05-12T14:09:19Z2017-05-12T14:09:19ZModularity<div><p>I've got a few minutes to run the corrected example and now I see what you meant. I don't know yet why it's happening. I don't have time right now to look into it. I'll try to find time for this over the week-end or next week.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/424473352017-05-12T14:25:49Z2017-05-12T14:25:51ZModularity<div><p>This is happening because there is a parent binding assigned by default for ChildContext<br>
<a href="https://github.com/robotlegs/robotlegs-framework/blob/master/src/robotlegs/bender/extensions/viewManager/impl/ContainerRegistry.as#L118">https://github.com/robotlegs/robotlegs-framework/blob/master/src/ro...</a></p>
<p>And then StageObserver triggers all bindings to handle ADDED_TO_STAGE<br>
<a href="https://github.com/robotlegs/robotlegs-framework/blob/master/src/robotlegs/bender/extensions/viewManager/impl/StageObserver.as#L109">https://github.com/robotlegs/robotlegs-framework/blob/master/src/ro...</a></p>
<p>I've temporary applied such a crutch, so it works:<br>
<code>containerRegistry.getBinding(contextView.view).parent = null;</code></p>
<p>Will consider you idea to not to trigger .initialize() seems like this method creates that binding, but project doesn't work properly without it - will get back later when I know if it possible to not to use .initialize()</p>
<p>Thank you again for support!</p></div>oleg3000tag:robotlegs.tenderapp.com,2009-10-18:Comment/424473352017-05-13T16:51:51Z2017-05-13T16:51:51ZModularity<div><blockquote>
<p>This is happening because there is a parent binding assigned by default for ChildContext</p>
</blockquote>
<p>Yep. You're right!</p>
<blockquote>
<p>I've temporary applied such a crutch, so it works:</p>
</blockquote>
<p>If it works for you, go for it, but I think that you somehow could avoid such workarounds.</p>
<p>I've modified my example, again. Hopefully this time without omissions of any kind:)<br>
I hope you'll understand what's going on in spite of the ugly layout.<br>
In this version there are:</p>
<ul>
<li>
<p>RootContextView - root context</p>
</li>
<li>
<p>ChildContextView with its own context - mediator mapped <strong>only</strong> in the child context</p>
</li>
<li>
<p>SharedContextView with its own context - mediator mapped <strong>only</strong> in the shared context</p>
</li>
<li>
<p>SimpleView - just a simple component with a mediator mapped <strong>only</strong> in the root context</p>
</li>
</ul>
<p>So, one hierarchical combination could be:</p>
<p>--- RootContext</p>
<p>------ChildContext</p>
<p>--------- SharedContext</p>
<p>-------------- SimpleView</p>
<p>Or:<br>
--- RootContext</p>
<p>--------- SharedContext</p>
<p>-------------- SimpleView</p>
<p>or:<br>
--- RootContext</p>
<p>------ChildContext</p>
<p>-------------- SimpleView</p>
<p>Since SimpleView does not have its own context, it has been mapped only inside of the root context. Only one new mediator would be created when an instance of SimpleView is added to one of the 3 context-views. So, each instance added to the stage will have its own mediator ( no duplicates).</p>
<p>SharedContext and ChildContext have their own context and mappings. There is no need to map them inside of RootContext as well!</p>
<p>I put SharedContext and SimpleView inside of the commons folder. They could as well be inside of a library of "widgets" or reusable components.</p>
<blockquote>
<p>The project1 contains from A,B,C Views. I want to have a (lets call it widget) widget1 which is actually a copy of project1, but it contains C View only. What do I want is to be able to add that widget1 into the project1 (as a child in view tree),</p>
</blockquote>
<p>If RootContextView is what you call project1, I still don't understand why you want to add a copy of RootContextView to itself.<br>
Anyway, obviously you'll have to map CMediator-CView only once in the root context.</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/424473352017-06-21T08:37:35Z2017-06-21T08:38:23ZModularity<div><p>Thank you so much for helping Ondina!<br>
Probably you're right and idea of putting context into itself is not such a good idea - but I really need it in my situation)<br>
Unfortunately I stopped to work on it as Flash is dying in our company(</p></div>oleg3000