tags:

views:

49

answers:

3

Hi,

I've got an architecture/logic question. This is what I'd like to achieve:

  • a) I've got three buttons in my main app.
  • b) When you click any of the buttons, a customs component based on a TitleWindow opens.
  • c) In the titleWindow is a yes/no selector.
  • d) If the answer is "yes", then I want to change the color of the button that was clicked in the main app to red. If the answer is "no" then nothing happens to the button in the main app.

My question is what is the best/easiest way to "remember" which button was clicked and handle the yes/no question.

Solution:

  • a) Make a variable with the id of the button that was clicked in the main app and set a public variable in the component to that id

  • b) And then make a custom event in the component that handles the yes/no question. The custom event would use the button id as a parameter and send that back to the main app.

Is there a better/easier way to do this? Am I approaching it correctly? Does it make sense to "send" the button id into the component and then back out again?

Thank you.

-Laxmidi

+1  A: 

I'd rather have a lastClickedButton private variable in the main application and set it whenever one of the buttons are clicked. When Yes button is clicked, the TitleWindow component would dispatch a normal event (with appropriate event type, say YES_CLICKED) which the main application would be listening for. Set the color of the lastClickedButton from the event handler.

The idea is that which button was clicked is an information relevant only to the main application - the TitleWindow component has nothing to do with it. When we pass the button id to the TitleWindow, we're unnecessarily creating a dependency on the main application. If in future you want to reuse the TitleWindow component for some other purpose, this button id variable will become meaningless there.

Amarghosh
Hi Amarghosh, Thank you for your help. I'm going to follow your advice. Your solution is straight-forward. You're right that which button was clicked is relevant only to the main app. Thank you.
Laxmidi
+1  A: 

Take a look at the command pattern for this.

When the button is pressed, pass a reference to the button that was clicked to the command.

If you are using Spring AS, something like this...

<mx:Button id="myButton1" click="EventBus.dispatchEvent(new CommandEvent('testButton', myButton1))" />

In the command, throw up your dialog, handle the response and set the style on the reference to the button that you passed in.

This decouples the logic of what you are doing from the UI component itself (It doesn't even need to be a button, the command could take a UIComponent).

It also doesn't leave state lying around your application, such as having which button was last clicked / etc as all the state for the piece of logic you are performing is encapsulated within the command.

Brief pseudocode of the command

public class TestUICommand implements Command, RequiresContext {
    private var _context : UIComponent;
    private var _dialog : MyDialog;

    // Your command controller would set the reference to the button here.
    public function set context( cxt : UIComponent ) : void {
        _context = cxt;
    }

    public function execute() : * {
        _dialog = new MyDialog();
        _dialog.popup();
        _dialog.addEventListener( "yes", doYes );
        _dialog.addEventListener( "no", closeDialog);
    }

    private function doYes( event : Event = null ) : void {
        _context.setStyle("color", 0xFF0000);
        closeDialog();
    }

    private function closeDialog( event : Event = null ) : void {
        _dialog.close();
    }
}
Gregor Kiddie
Hello Gregor Kiddie, Thank you for your help. Unfortunately, I'm a novice, so I don't use inversion control frameworks, yet. I'll have to study your solution so more. Again, thank you for taking the time to help me.
Laxmidi
The lo-fi way of doing it (without a framework) would be to have your click handler do var myCommand = new TestUICommand(); myCommand.context = event.target; myCommand.execute(); This would have pretty much the same effect, and still keep it nicely decoupled.
Gregor Kiddie
+1  A: 

You can do this very easily without a lot of coding. Assuming you have a different TitleWindow showing for each button you want to turn red, you just make the "want to be red" buttons predicate their styleName off of the toggled state of the clicked button in each title window. You would have to set the toggle property of the TW buttons to true=, of course, and then get their selected property.

Example:

<mx:Button styleName="{titleWindow_01.yesButton.selected ? 'redStyle' : 'plainStyle'}" text="Blah"/>

And in your TitleWindow

<mx:Button id="yesButton" toggle="true" text="Yes"/>

These buttons will obviously have other attributes, but this gives you a bare-bones idea of how easy this is to do without a lot of coding. Binding will automatically take place, so you don't even need to worry about that.

Robusto
Hi Robusto, Thank you for the advice.
Laxmidi