Create parent object that creates child objects using commands

Matt's Avatar

Matt

29 Aug, 2012 08:34 AM

I'm completely new to RL and am in the process of building a fairly large, UI based application.

In the app there is a menu bar, and when the current selection changes CreateSceneViewCommand is used to create a SceneView.

Within the SceneView display object I want to nest child objects that have their own commands and mediators. How should I go about this?

Should I dispatch events from the SceneViewMediator that the context picks up and then creates the child objects? If so then how do I add the child objects to the correct SceneView parent object? Should I dispatch the events with a reference to the parent container?

... or in CreateSceneViewCommand should I issue more commands that creates the child objects and wraps them in some sort of SceneView parent object?

Basically I want a nice way of grouping views within a SceneView... but am struggling to understand the best procedure for achieving this.

  1. Support Staff 1 Posted by Ondina D.F. on 29 Aug, 2012 09:09 AM

    Ondina D.F.'s Avatar

    Hi Matt,
    The recommended practice is to avoid working on Views in Commands, if possible. Commands are usually responsible for application logic, application’s behaviour and they act upon Models and Services, usually in response to user interactions with the application.
    View logic (adding/removing sub-views, components) should happen in the View.

    Though, there might be situations where using Commands to manage Views can not be avoided.

    A very simple scenario: if a View (SceneView) needs to add some subviews in response to user interactions (selectedIndex changes) happening in another View (NavigationView containing a List), then the flow would be something like this:

    • NavigatorView dispatches a custom event within the handler function for the list

    • NavigatorMediator redispatches it

    • SceneMediator listens for that event and calls SceneView’s API passing the payload of the event as an argument (array of View classes that need to be added to the SceneView)

    • SceneView adds/removes subviews accordingly

    • The mediators for the sub-Views will be created automatically (http://knowledge.robotlegs.org/kb/reference-mvcs-implementation/are...)

    Now, it is not very clear how your use case looks like. Do you need to add different sub views every time you create an instance of the SceneView, or are they always the same? First instance of SceneView contains SubViewA, SubViewB and SubViewC, second instance of SceneView contains SubViewD, SubViewA, SubViewE ?
    Do you need to add/remove the views dynamically?

    Could you describe your use case in more detail, so we can see if you really need Commands to manage your Views?

    If so then how do I add the child objects to the correct SceneView parent object?

    Does this mean that several SceneView instances coexist in the same parent View?

    Basically I want a nice way of grouping views within a SceneView... but am struggling to understand the best procedure for
    achieving this.

    Is it a visual grouping or a functional one?

    More questions :)
    Which version of robotlegs are you using?
    Is it an actionscript or a Flex project?
    Is it a mobile, browser or desktop app?

    Cheers,
    Ondina

  2. 2 Posted by Matt on 29 Aug, 2012 10:13 AM

    Matt's Avatar

    Hi Ondina,

    Thanks for the very quick response :)

    To answer your initial questions -
    Robotlegs version = 1.5.2
    Project type = Actionscript only / Desktop AIR app
    I'm currently using RL out of the box with no additional frameworks.

    This is how the app needs to work -

    You can think of the application as almost like a website, where you have a menu bar that loads in different scenes (SceneViews). There are several menu options, which will all create different SceneViews. When a new SceneView loads in, the old one is destroyed - so there is only ever 1 SceneView on the stage at a time.

    A SceneView contains more objects, so I thought it would be logical to group these objects together (hence the idea of using a SceneView in the first place). I suppose this is a functional way of grouping the objects because they will interact with each other. It also means when I want to destroy a SceneView, I can call dispose(), and the SceneView will manage its cleanup of child objects.

    Each SceneView is different, because it will contain a different collection of child objects (however sometimes particular child objects may be reused across different scenes).

    The child objects are quite complex in themselves. Ideally I would like the child objects to be dispatching their own events which can get picked up by some mediator or the context, and trigger it's own commands.

    Current flow of events -

    1. NavigatorModel dispatches event saying the selected menu item has changed

    2. Event is picked up by the context

    3. The context runs ChangeSceneCommand, which tells the SceneModel to change the current scene (it passes in an identifier for the selected scene so it can work out which scene to change to).

    4. SceneModel works out which scene should be selected, and dispatches an event saying to create that scene. E.g. SceneEvent.CREATE_HOME

    5. The context picks this up, and runs the CreateHomeSceneCommand

    6. The CreateHomeSceneCommand creates the correct SceneView and adds it to the stage.

    This is all working, but is currently where I'm stuck... where do I add the objects that are inside SceneView?

    My comments from your reply -

    It looks like you are saying that the SceneView should be creating its own child objects. How is this done exactly? Ideally in SceneView I want to make a command get triggered on the context that says 'CreateObjectA' and 'CreateObjectB' etc.... Is this possible with commands, and how does the command know where to add the object? Or, should I just go ahead and create the objects directly in the SceneView? If I do the latter, it seems that I am loosing the ability to use commands to do things, which I quite like doing!

    Hope all this makes sense!

  3. Support Staff 3 Posted by Ondina D.F. on 29 Aug, 2012 11:30 AM

    Ondina D.F.'s Avatar

    No problem, Matt:)

    Thanks for providing more details!

    I've got some work I need to finish up, so I’ll reply to that later. Ok?

  4. 4 Posted by Matt on 29 Aug, 2012 02:00 PM

    Matt's Avatar

    Nice one, looking forward to your response.

    Cheers,

    Matt

  5. Support Staff 5 Posted by Ondina D.F. on 29 Aug, 2012 03:49 PM

    Ondina D.F.'s Avatar

    You can think of the application as almost like a website, where you have a menu bar that loads in different scenes (SceneViews). There are several menu options, which will all create different SceneViews. When a new SceneView loads in, the old one is destroyed - so there is only ever 1 SceneView on the stage at a time.

    I’m still not clear on this :)
    Are these SceneViews different Views with different Mediators, like in HomeView+HomeViewMediator, ImagesView+ImagesMediator, UsersView+UsersMediator, etc? Or are you adding and removing the same SceneView and the only thing that’s different each time is which sub views will reside inside of it?

    Each SceneView is different, because it will contain a different collection of child objects (however sometimes particular child objects may be reused across different scenes).

    If only the subviews are different and SceneView is always the same and its only responsibility is to add/remove subviews, then I wouldn’t remove SceneView from the display list and add it again when the selectedIndex of the menu changes. I would only repopulate it with the collection of child objects required by the change in the menu.

    But maybe you have HomeView, ImagesView, UsersView extending a base SceneView which a common functionality like addSomeViews() / removeSomeViews() ?

    Here is what I would do:

    1. Use case SceneView is the same, sub-views are different:
    2. Use case several Views(HomeView, Usersview) with several subviews, some of them reused
    3. Use case 3 – your use case using commands

    Use case 1: -I’d create a custom event class NavigatorEvent, a Model NavigatorModel and a Command NavigatorCommand (please excuse the made up names of the classes)

    -NavigatorView contains SomeMenuBar with items like Home, Images, Users and SceneView

    -Within someMenuBar_ changeHandler() : dispatchEvent(new NavigatorEvent(NavigatorEvent.NAVIGATION_INDEX_CHANGED, event.currentTarget.selectedItem));// Home, Images etc

    -NavigatorView.onRegister() addViewListener(NavigatorEvent.NAVIGATION_INDEX_CHANGED, dispatch, NavigatorEvent);// redispatching the event on the shared event dispatcher

    [EDIT] NavigatorView.onRegister() should read NavigatorMediator.onRegister()

    -this will trigger NavigatorCommand (mapped to NavigatorEvent.NAVIGATION_INDEX_CHANGED)

    -NavigatorModel and NavigatorEvent are injected into NavigatorCommand

    -NavigatorCommand.execute() navigatorModel.geSubViewsArray(navigatorEvent.selectedItem);//event’s payload containing the name of the selectedItem

    -NavigatorModel accesses a collection of View Classes mapped to the different menu items, either defined in the Model or in a VO.

    Let’s say :
    subViewsArray[“Home”]=[SomeView, AnotherView, HelpView];
    subViewsArray[“Images”]=[ImagesListView, ImageDetailView, HelpView];
    and so on

    -within navigatorModel.geSubViewsArray dispatch(new NavigatorEvent(NavigatorEvent.NEEDED_SUBVIEWS, subViewsArray[selectedItem]));

    -SceneMediator added a listener for NavigatorEvent.NEEDED_SUBVIEWS addContextListener(NavigatorEvent.NEEDED_SUBVIEWS, onAddSubViews, NavigatorEvent);

    -onAddSubViews():view.addSubViews(event.viewsArray);

    -SceneView.onAddSubViews(viewsArray:Array) removes all previous subviews and then iterates through viewsArray
    and creates the views:
    viewToAdd=new viewsArray[i];
    and adds it to the display list.

    Use case 2: NavigatorView has to add new Views depending on the selectedItem from the menu bar. Same as in use case 1, NavigatorView dispatches an event to trigger NavigatorCommand, which calls a method navigatorModel.getViewForSelectedItem() or something.

    The Model returns the name of the View associated with the selected item from a collection or VO and also an array of SubViews mapped to that View. NavigatorMediator passes the event payload to NavigatorView, which will remove the previous view and add the new view.

    Here it becomes tricky. How to let the new View know which subviews it has to add?

    Option 1: after NavigatorView creates the View (say HomeView) it passes the array of subviews through HomeView’s API: set subViewsArray(subViewsArray:Array)

    Option2: HomeViewMediator onRegister dispatches an event to trigger another command that reads the subViewsArray from a Model and the flow would be the same as in use case 1

    Option 3: use Stray’s RelaxedEventMap (I’ll provide a link, if need be)- that way HomeViewMediator would be able to react to the same event dispatched by the NavigatorModel from above.

    Option 4: factory pattern – for that one you’ll have to search and read the discussions on this topic on this forum

    Use case 3:

    This is all working, but is currently where I'm stuck... where do I add the objects that are inside SceneView?

    The command creating the main Views (HomeView, UsersView, ImagesView) can access a Model (same Model or a different Model, depending on your needs) containing the collection of subviews mapped to the menu’s selected items, and after creating HomeView, for example, it iterates through the array of children (SomeView, AnotherView, HelpView) and creates and adds them to HomeView.
    Of course, in this scenario you’d have to know which the previous View was, so you can remove it from the display list.

    Wow, I wrote half a novel. Hopefully it wasn’t too confusing ;)

    If you need more clarifications or have more questions, I’ll answer tomorrow.

    Ondina

  6. Support Staff 6 Posted by Ondina D.F. on 31 Aug, 2012 08:49 AM

    Ondina D.F.'s Avatar

    We've been getting a lot of spam lately on our forum (powered by Tender).
    It seems they are constantly trying to update their spam filters. Even though, at times, the amount of spam slipping through is quite impressive, and.. annoying.

    Sorry for the inconvenience.

    I’m going to close this discussion, before it gets flooded with spam. If you want to continue this discussion, feel free to reopen it.

    Cheers,
    Ondina

  7. Ondina D.F. closed this discussion on 31 Aug, 2012 08:49 AM.

  8. Matt re-opened this discussion on 05 Sep, 2012 10:40 AM

  9. 7 Posted by Matt on 05 Sep, 2012 10:40 AM

    Matt's Avatar

    Thanks very much for your detailed response with this question.

    You've definitely given me a lot to go and think about so I'll do some research and re-open this thread if I have some more questions.

    Thanks,
    Matt

  10. Matt closed this discussion on 05 Sep, 2012 10:41 AM.

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