one event, multiple commands

hello's Avatar

hello

11 May, 2015 05:28 AM

Hi there,

I am new to robotlegs.

I have a list of items that can be selected.

Every time item is selected I need to perform to actions:

  • set this item as a "clicked" and update list (all "clicked" items will be marked with red color)
  • navigate to external site

What would be best way to solve this?

1) I was thinking about mapping 1 single event to 2 different commands, that is sth like:

commandMap.map(MyList.SELECTED, MyList).toCommand(OpenExternalURLCommand);
commandMap.map(MyList.SELECTED, MyList).toCommand(MarkItemAsOpened);

2) Or maybe just one command that is performing to actions?

commandMap.map(MyList.SELECTED, MyList).toCommand(OpenItemAndMarkItAsOpenedCommand);

thanks!

  1. Support Staff 1 Posted by Ondina D.F. on 11 May, 2015 11:07 AM

    Ondina D.F.'s Avatar

    Hi,

    Of course it is a good practice to have classes following the SRP (single responsibility principle), so having 2 commands for 2 different actions is perfect, especially if you need to trigger those commands separately from different parts of your application. But, in this case, you'd have to use 2 different event types to trigger the 2 commands and better names for your commands and event types.

    I'm assuming that MarkItemAsOpened is a command that accesses a model, right?
    MarkItemAsOpened is too generic of a name. Which item should be marked? What if there are several lists in your app?
    OpenItemAndMarkItAsOpenedCommand is also not a good name.
    But, I guess that the names you used were just an example for the sake of the discussion and you're not going to use them in your real code.

    Anyway, let's say that your list is a users list inside of a UsersListView. When a list item is selected you want to update the UsersModel, setting the selected item, and then you want to open a UserDetailsView with some data loaded from a server.

    The event that you are dispatching from view would be a UserEvent.USER_SELECTED. The UsersListMediator would redispatch it and trigger an UpdateUsersCommand that would access a UsersModel.

    Another event type would be UserEvent.LOAD_USER_REQUESTED that would trigger a LoadUserCommand, where you'd access a UserService.
    The names of the view, mediator, event, model, service and commands, are now representing a functional unit in your application.

    Where you dispatch UserEvent.LOAD_USER_REQUESTED is up to you.
    If after updating the model you'd always want to load user's data, you could dispatch the LOAD_USER_REQUESTED event from within the UpdateUsersCommand.

    There are cases where accessing the model and then the service within the same command wouldn't be such a big violation of the SRP. If you're sure that user selected will always be followed by a load user details, then you can simply do that inside of the same command.
    Maybe you could have a CreateUserCommand, a LoadUserCommand, an SaveUserCommand, and a DeleteUserCommand, etc. Each command accesses the UserModel before calling the service to perform the desired action. So, each command would be injected with an IUserModel and with an IUserService and would call the appropriate methods on these classes.

    But, if you'd need to dispatch an event to trigger a command that would access a service from several parts of your application, the above wouldn't be a good solution, because maybe you won't always want to also update the model before accessing the service.

    If you're not sure what to do, start with having separate commands, one (or as many as needed) for manipulating the model and other(s) for calling the service.
    After gaining more experience with robotlegs you'll know when you can deviate a little from the rules ;)

    Hope this helps
    Ondina

  2. 2 Posted by hello on 12 May, 2015 06:50 AM

    hello's Avatar

    wow! so detailed answer! :)
    thank Ondina!

    what I eventually did:

    1) CustomItemRenderer dispatch

    new ListEvent(ListEvent.SELECTED, data)

    2) ListViewMediator listen for this event, and redispatch it

    new ListEvent(ListEvent.SELECTED, data)

    3) OpenExternalURLCommand is executed and Service is called.

    4) Service do both jobs:

    • open external link
    • dispatch new ItemEvent(ListItemEvent.OPENED, data);

    5) MarkItemAsOpened is called.

    -Model is accessed, and the item is marked as "opened"

    -event is dispatched: new ListEvent(ListEvent.UPDATED, item);

    6) ListViewMediator is informed and update its list

    What do you think?

  3. Support Staff 3 Posted by Ondina D.F. on 12 May, 2015 08:05 AM

    Ondina D.F.'s Avatar

    You're welcome:)

    I think that the workflow you described is perfect. The only thing I'd do a bit differently would be the naming of the event types, namely I'd be more specific: instead of SELECTED I'd say ITEM_SELECTED , but that's just a matter of preferences.
    Also instead of ListEvent I'd use a slightly different name to avoid possible confusions with the already existing mx.events.ListEvent.

  4. Ondina D.F. closed this discussion on 01 Jul, 2015 06:42 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