Mediator for flex Dynamic Skin part
Hi
When I create dynamic skin parts in a SkinnableContainer using typical code below, if I have the dynamic Skin part class matched to a Mediator as normal in a COntext it does not fire the Mediator :
In COntext :
mediatorMap.mapView(BugContainer, BugContainerMediator);
In SkinnableContainer :
for (var item:Number=6; item < bugs+6; item++) { var
bugItem:BugContainer = createDynamicPartInstance("bug") as
BugContainer; bugItem.canID = item; bugsArray.push(bugItem); var
bug:BugContainer = bugsArray[0] as BugContainer; (this.skin as
MainSkin).iconGroup.addElement(bugItem);
}
Has anyone tried to do something similar, and have a solution to my problem?
Thanks
Duncan
Comments are currently closed for this discussion. You can start a new one.
Keyboard shortcuts
Generic
? | Show this help |
---|---|
ESC | Blurs the current field |
Comment Form
r | Focus the comment reply box |
---|---|
^ + ↩ | Submit the comment |
You can use Command ⌘
instead of Control ^
on Mac
Support Staff 1 Posted by Ondina D.F. on 06 Apr, 2014 09:10 AM
Hello Duncan,
I've just tried out an example with dynamically added skin parts (Buttons). It works well on my end. The Buttons are added to a Group and their mediators are created when they are added to the stage.
What kind of components are BugContainer and its parents?
Is it possible that your bugs-component or its parent are top-level components, like Alert, PopUp, Window, etc? If that's the case, than it will be created 'outside' of the robotlegs-context's scope and the framework won't be able to automatically create a mediator for this component. See: http://knowledge.robotlegs.org/kb/reference-mvcs-implementation/how...
Try out your use case in a simple example where you make sure that your component and/or its parent are "normal" display objects. Let us know whether the issues persist or not. If you still have problems with mediators creation, please attach the example for us to take a look at it.
Ondina
Support Staff 2 Posted by Ondina D.F. on 06 Apr, 2014 10:03 AM
To verify my assumption from the previous post, try this:
When you create your context with the root display object ( Application or WindowedApplication ) as a contextView, instead of using "this", use this.parent, which is the mx_managers_SystemManager. If the mediators for your skin parts are created, it confirms that the components for your skin parts are not added to the contextView's stage, but to its parent's stage, the SystemManager stage ( top level).
3 Posted by duncmcm on 08 Apr, 2014 07:12 PM
Hi Ondina
My BugContainer is just a SkinnableContainer, I also tried using this.parent and it comes up with :
warning: unable to bind to property 'parent' on class 'AppName'
Could you post your solution and I will take a loo at it
Thanks
Duncan
Support Staff 4 Posted by Ondina D.F. on 09 Apr, 2014 11:13 AM
Hey Duncan,
First of all, I have to confess that I somehow overlooked the fact that you were using robotlegs v1, so I used robotlegs v2 for testing your use case with the rating_demo from this article:
http://www.adobe.com/devnet/flex/articles/dynamic_skin_parts.html
The RatingSkin uses a Button with (id= 'ratingButton' ) as a dynamically added skin part. I replaced it with a custom component RatingButton extending a Button and I mapped it to a RatingButtonMediator. The RattingButton is added to a ratingGroup (HGroup) which is a child of a PopUpAnchor, which in turn is added to the SystemManager's stage. Because of that, the mediators for the RatingButtons are not created automatically.
The solutions for rl2:
either use viewMannager.addContainer( ratingGroup) inside of RatingView's mediator.
or mediate the RatingView and let it handle the skin parts
or create the context with the SystemManager as a contextView. I'd use this only if there are no other options
If the RattingButtons would be added to a container whose parent would be the contextView, the mediators would be created automatically and no workaround would be needed.
After your response, I tried the example with rl1, and, indeed, it didn't work even when using SystemManager as a contextView. The only solution would be to create the mediators manually inside of RatingView's mediator, when the skin parts are added, but that's rather cumbersome.
I simply didn't question the fact that you wanted to mediate the components used as skin parts, because I thought you might have had good reasons for doing so. But, maybe you don't need a mediator for each skin part added, because the RatingView from my example could dispatch custom events whenever a user interacts with the RatingButtons, and RatingMediator could handle them. Personally, I would opt for this solution anyway.
Robotlegs v2 implements a better mechanism for handling and managing views than robotlegs v1, among other improved features. I strongly recommend using rl2 instead of rl1, if possible :)
If you decide switching to rl2 and you need help, I will go into details about how to use the viewMannager.addContainer and so on.
That's probably because you're creating the context inside fx Declarations, where you don't have access to the SystemManger yet. I usually initialize the context in actionscript in the preinitialize handler of the application, and there this.parent is the SystemManager.
When using Declarations, if you want to pass the parent of the contextView to your ApplicationContext, do this:
Let me know how it goes.
Ondina
5 Posted by duncmcm on 17 Apr, 2014 06:14 PM
Hi Ondina
Yes I go this to work OK using RB2. Thanks I now have Mediators initized for my dynamic skin parts.
Once I built up my application further I come across another few issues I hope you can help again, and I really do appreciate your support.
I have 3/4 contexts within my app. All are defined using the ContextBuilder declaration using a Bundle which then defines a COntextConfig. My requirements are that :
I need to let the sub contexts know about the top level context state, maybe via a Model singleton.
I need to dispatch top level context events which are picked up by lower level contexts
What are the best ways to do these? I have tried to define a singleton Model on the top level COntext , and then inject this Model into a sub context without any luck , they are always seperate instances of the model.
Thanks again
ps I have looked at an example two contexts example at :
http://knowledge.robotlegs.org/discussions/robotlegs-2/6915-best-pr...
But this example is actually using the SAME context class for each context which is not what I want.
Support Staff 6 Posted by Ondina D.F. on 18 Apr, 2014 09:52 AM
Good decision :)
You're welcome.
Hehe, Duncan, you made me think I made a mistake, so I looked at my example again.
It's not the same context class! There are 2 context classes. They only look similar and have the same class name, but one belongs to the "shell" and the other to the "module"(see package names). You can look at the log messages in debug mode to see how robotlegs initializes the 2 contexts. You can rename the 2 RobotlegsContext classes, if you want.
Or, did you mean something else?
Each display object that is used as a contextView should initialize its own context with its own configs.
In my example, ShellMainView initializes the parent context, where "this" is ShellMainView, and SomeView initializes a child context, where "this" is SomeView.
Did you do that? Or, did you try to initialize all 3 contexts inside your root display object? If you did the latter, then that's probably why you encountered some issues.
In my example, the top level context (the shell context) is mapping a Model as a singleton, inside of yourdomain.shell.configs.ModelsConfig:
injector.map(ISomeModel).toSingleton(SomeModel);
The model is then injected successfully into yourdomain.modules.singleModule.views.mediators.SomeMediator:
[Inject] public var someModel:ISomeModel;
That happens because the child context is inheriting the dependencies from the parent context, when using the default MVCSBundle, which lets the context install a ModularityExtension with 'inherit' and 'expose' set to true by default.
See: https://github.com/robotlegs/robotlegs-framework/blob/master/src/ro...
inherit Should this context inherit dependencies from a parent context?
expose Should this context expose its dependencies to child contexts?
So, if SomeModel is mapped in the parent context, the child context will inherit the mapping and the child injector will inject the class wherever you define an injection point. The parent and the child contexts will share the same model (same instance).
If, on the contrary, you wanted the child context to use a different instance of SomeModel, you'd have to map SomeModel inside of yourdomain.modules.singleModule.configs.ModelsConfig (the config class of the module/child context). The child injector would use this rule instead of the parent's rule, and as a consequence, the 2 contexts will have different instances of SomeModel to work with.
Just play around with my example to see how it works. There is also a link to another example in the mentioned discussion, ondina-robotlegs-bender-shared-configs.zip, where you can see different ModularityExtension's settings.
The ModuleConnector is what you need.
Try out these examples :
https://github.com/Ondina/robotlegs-bender-as3-modular-example
https://github.com/Ondina/robotlegs-bender-modular-air
The readme files are still a work in progress, but I think you'll get the idea:)
This one is using signals instead of events:
https://github.com/dotdotcommadot/ModularRL , but, I suggest to get familiar with the modular connector using events first.
Don't hesitate to ask questions in here, if you get stuck. Actually, it is better to open a new discussion, under robotlegs 2, if the problems aren't related to the dynamic skin parts anymore. Just let me know, if the ModuleConnector examples are what you need and whether this discussion can be marked as resolved.
Ondina
Ondina D.F. closed this discussion on 28 Apr, 2014 08:11 AM.