Using Robotlegs App as Component

truthreveller's Avatar

truthreveller

23 Nov, 2011 06:10 PM

Hi,

I am created a DatePicker component using Robotlegs, using MVC to allow re-skinning of the component easily. My problem is I am unsure the best practice to set properties on the component from inside another application that is using the component. Example I would like to set the initial date of the DatePicker component. I had a few ideas on different approaches, but none of them seemed correct.

Example my Robotlegs application (component) is DatePickerComponent:

var datePicker:DatePickerComponent = new DatePickerComponent;
datePicker.date = new Date(1975, 0, 1);

Would I use a Service class to allow other applications to set initial states of the component?

datePicker.myService.date = new Date(1975, 0, 1);

Thanks for any insight,
Paul

  1. Support Staff 1 Posted by Ondina D.F. on 23 Nov, 2011 06:22 PM

    Ondina D.F.'s Avatar

    Hi Paul,

    This discussion is marked as private. Was this your intention?

  2. 2 Posted by truthreveller on 23 Nov, 2011 08:41 PM

    truthreveller's Avatar

    Opps don't know how it was published as private, thanks.

    Paul

  3. Support Staff 3 Posted by Ondina D.F. on 24 Nov, 2011 11:40 AM

    Ondina D.F.'s Avatar

    Hi Paul,

    In the following code snippets I’ll show you an oversimplified scenario:
    CalendarView (DateChooser)
    CalendarMediator
    CalendarModel
    CalendarEvent
    CalendarCommand

    The flow:
    1. CalenderView.datechooser_changeHandler() ->CalenderEvent-> CalendarMediator-> CalenderEvent-> CalendarCommand->CalendarModel-> CalenderEvent->rest of the application
    2. rest of the application-> CalenderEvent->CalendarMediator-> CalenderView. initilizeCalendarDate()

    The CalendarMediator would be the bridge between your CalendarView and the rest of your application.
    If you need to set the date on your DateChooser, you can let CalendarMediator access a public method in your CalendarView: initilizeCalendarDate()

    CalendarMediator

    
    public class CalendarMediator extends Mediator
    {
    
    [Inject]
    public var view:CalendarView;
    
    override public function onRegister():void
    {
         eventMap.mapListener(eventDispatcher, CalendarEvent.INITIALIZE_CALENDAR_DATE, onInitializeCalendarDate);
    eventMap.mapListener(view, CalendarEvent.CALENDAR_SET_DATE, dispatch);
        view.initilizeCalendarDate('2011/11/11');
    }
    
    protected function onInitializeCalendarDate(event:CalendarEvent):void
    {
       view.initilizeCalendarDate(event.someDate);
    }
    }
    

    CalendarView.mxml

    
    import com.robotlegs.demos.robotlegsincremental.controllers.events.CalendarEvent;
    import mx.events.CalendarLayoutChangeEvent;
    
    public function initilizeCalendarDate(dateData:String):void
    {
       dateChooser.selectedDate=new Date(dateData);
    }
    protected function datechooser_changeHandler(event:CalendarLayoutChangeEvent):void
    {
    var date:Date=event.target.selectedDate;
    if (date != null)
    dispatchEvent(new CalendarEvent(CalendarEvent.CALENDAR_SET_DATE, date));
    }
    

    If you need to send a chosen date to another component in your application, you can let CalendarView dispatch an event(CalendarEvent.CALENDAR_SET_DATE) with the selectedDate as a payload and CalendarMediator, who has registered an event listener for it, would re-dispatch it.

    CalendarCommand previously mapped like this: commandMap.mapEvent(CalendarEvent.CALENDAR_SET_DATE, CalendarCommand, CalendarEvent, true);

    would do this:

    
    public class CalendarCommand extends Command
    {
    [Inject]
    public var calendarEvent:CalendarEvent;
            
    [Inject]
    public var calendarModel:CalendarModel;
    
    override public function execute():void
    {
        calendarModel.someDate=calendarEvent.someDate;
    }
    }
    

    CalendarModel

    
    public class CalendarModel extends Actor
    {
    protected var _someDate:String;
    
    public function get someDate():String
    {
    return _someDate;
    }
    
    public function set someDate(value:String):void
    {
    _someDate = value;
    dispatch(new CalendarEvent(CalendarEvent.CALENDAR_DATE_CHANGED, someDate));
    }
    }
    

    Other parts in your application would register a listener for CalendarEvent.CALENDAR_DATE_CHANGED and could use the date.

    CalendarEvent

    
    public class CalendarEvent extends Event
    {
            public static const CALENDAR_SET_DATE:String="calendarSetDate";
        public static const CALENDAR_DATE_CHANGED:String="calendarDateChanged";
        public static const INITIALIZE_CALENDAR_DATE:String="initializeCalendarDate";
    
            public function CalendarEvent(type:String, someDate:String=null, bubbles:Boolean=false, cancelable:Boolean=false)
            {
                _someDate=someDate;
                super(type, bubbles, cancelable);
            }
    
            private var _someDate:String;
    
            override public function clone():Event
            {
                return new CalendarEvent(type, someDate, bubbles, cancelable);
            }
    
            public function get someDate():String
            {
                return _someDate;
            }
    }
    

    I hope this gives an idea of how to make a DateChooser reusable.
    Let me know what you think:)

    Ondina

  4. 4 Posted by truthreveller on 24 Nov, 2011 07:17 PM

    truthreveller's Avatar

    Wow really great response, your code is really well structured.

    If the Robotlegs Calendar application is inside another non-Robotlegs application, is there anyway to dispatch events to the application such as the "CalendarEvent.INITIALIZE_CALENDAR_DATE" event?

  5. Support Staff 5 Posted by Ondina D.F. on 25 Nov, 2011 12:20 PM

    Ondina D.F.'s Avatar

    Hi Paul,

    Since you want to communicate between a Non-Robotlegs-Application and a Robotlegs-Application loaded as a Module, the best way, in my opinion, is to use an interface, as you’d do with any other modules.

    But if you want to communicate via events, you can use a sharedEventDispatcher and a DynamicEvent.

    NonRobotlegsApplication

    
    Application
    import mx.events.ModuleEvent;
    import mx.events.DynamicEvent;
    
    protected const MODULE_URL:String="RobotlegsAsModule.swf";
    private var sharedEventDispatcher:IEventDispatcher;
    
    protected function loadModule():void
    {
    sharedEventDispatcher=moduleLoader.loaderInfo.sharedEvents;
    sharedEventDispatcher.addEventListener("moduleToMainEvent", onModuleDataChanged, false, 0, true);
    moduleLoader.loadModule(MODULE_URL);
    }
    
    protected function onModuleDataChanged(event:DynamicEvent):void
    {
    dataFromModule.text=event.data as String;
    }
    
    protected function sendDataToModule():void
    {
    var dynamicEvent:DynamicEvent=new DynamicEvent("applicationToModuleEevent");
    dynamicEvent.data="APPLICATION TO MODULE";
    sharedEventDispatcher.dispatchEvent(dynamicEvent);
    }
    

    RobotlegsAsModule

    
    Module
    private var sharedEventDispatcher:IEventDispatcher;
    import mx.events.DynamicEvent;
    
    protected function module_creationCompleteHandler(event:FlexEvent):void
    {
    sharedEventDispatcher=systemManager.loaderInfo.sharedEvents;
    sharedEventDispatcher.addEventListener("applicationToModuleEevent", onApplicationDataChanged, false, 0, true);
    }
    
    protected function onApplicationDataChanged(event:DynamicEvent):void
    {
    dataFromApplication.text=event.data as String;
    }
    
    protected function sendDataToApplication():void
    {
    var dynamicEvent:DynamicEvent=new DynamicEvent("moduleToMainEvent");
    dynamicEvent.data="ROBOTLEGS MODULE TO APPLICATION";
    sharedEventDispatcher.dispatchEvent(dynamicEvent);
    }
    

    Note that the event listeners have a weak reference!
    A strong reference to the sharedEventDispatcher would prevent the module from being garbage collected.
    I hope this helps.
    Maybe somebody else will chime in with a better solution, in case there is one :)

    Ondina

  6. 6 Posted by truthreveller on 25 Nov, 2011 06:48 PM

    truthreveller's Avatar

    I like both your ideas. Thanks Ondina. :)

  7. truthreveller closed this discussion on 25 Nov, 2011 06:48 PM.

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