PureMVC Architects Lounge

Announcements and General Discussion => Getting Started => Topic started by: ArgV on March 18, 2008, 03:50:14



Title: Using PureMVC and the ExternalInterface
Post by: ArgV on March 18, 2008, 03:50:14
Hi folks,

i'm currently evaluating pureMVC for my next flex-app. but i'm already not so deep in PureMVC in. so for my project i need additional to my ws-soap,rpc-services a ExternalInterface communication. so my question is....where/how can i intergrate the externalinterface in the pureMVC architecture or should it be besides the pureMVC framework? what are the best options?


thanks

daniel


Title: Re: Using PureMVC and the ExternalInterface
Post by: puremvc on March 18, 2008, 09:54:32
The surrounding JavaScript and browser DOM is really just an extension of the View. The user clicks around in it, it has some black box implementation (which we really don't want to know a lot about inside PureMVC), and we may need to send data to it or invoke methods on it, and it may need to talk back to us. The same as any viewComponent.

Therefore, use a Mediator for communicating with the ExternalInterface, as it is built specifically for the purpose of Mediating communications between boundary objects in the view and the rest of the application.

Inside the ExternalInterfaceMediator, you might do something like:
:
import flash.external.ExternalInterface;

public static const NAME:String = 'ExternalInterfaceMediator';
public function ExternalInterfaceMediator()
{
   super(NAME, null);
   if (ExternalInterface.available)
   {
       // a method that will be invoked from JavaScript
       ExternalInterface.addCallback("sendFlashSomeData",  onSendFlashSomeData);
   }
}

protected function onSendFlashSomeData(dataForFlash:Object):void
{
   sendNotification( PROCESS_EXTERNAL_DATA, dataForFlash ); // let a Command handle this
}

override public function listNotificationInterests():Array
{
   return [ SEND_DATA_TO_JS,
              SIMPLE_JS_CALL,
              QUERY_JS  ];
}


override public function handlNotificationInterests(note:INotification):void
{
   if (ExternalInterface.available) {
      switch (note.getName())
      {
     
         SEND_DATA_TO_JS:
            ExternalInterface.call(note.getBody() as Object);
            break;

         SIMPLE_JS_CALL:
            ExternalInterface.call("noArgsJSMethod");
            break;

         QUERY_JS:
            var jsq:Boolean = ExternalInterface.call("jsCheckStringMethod", note.getBody as String);
            sendNotification(JS_QUERY_RESULT, jsq);
            break;
      }
   }
}


-=Cliff>


Title: Re: Using PureMVC and the ExternalInterface
Post by: trilec on March 18, 2008, 06:02:03
also an approch for deep linking..ie SWFAddress?



Title: Re: Using PureMVC and the ExternalInterface
Post by: jgervin on May 29, 2009, 08:36:07
Cliff, I have copied your example, but it appears that my ExtInterfaceMediator isn't hearing any of the callbacks.  Firebug tells me the functions have been called, but my swf isn't hearing them. Any suggestions?

.....
public class ExternalInterfaceCommand extends SimpleCommand
    {
       // Called by the MacroCommand
       override public function execute( note : INotification ) : void
       {
             
            // Create and register proxy
            if( facade.hasMediator( ExternalInterfaceMediator.NAME ) ){
               return;
            }else{
               facade.registerMediator( new ExternalInterfaceMediator() );
            }
           
       }
    }
........

MEDIATOR
......
public class ExternalInterfaceMediator extends Mediator implements IMediator
   {
      
        private var _httpservice:HTTPService;
       
      public static const NAME:String = 'FABridgeMediator';
      
      
      public function ExternalInterfaceMediator()
      {
         super(NAME, null);
         // Add Listeners
         
         if (ExternalInterface.available)
         {
            ExternalInterface.marshallExceptions = true;
            
              // a method that will be invoked from JavaScript
              ExternalInterface.addCallback("filterMap", onFilterMap);
              ExternalInterface.addCallback("launchOpeningInfo", onLaunchOpeningInfo); // <<--- Need to put this in the javascript
              ExternalInterface.addCallback("refresh", onRefreshTheData);
              ExternalInterface.addCallback("switchMode", onSwitchMode);
              ExternalInterface.addCallback("switchLayout", onSwitchViews);
         }
      }
      
      
      
            public function onFilterMap( filtertype:String ):void {
               /* var fse:FilterSelectedEvent = new FilterSelectedEvent( FilterSelectedEvent.FILTER_SELECTED_EVENT, true, false, filtertype);
                fse.filterGroupName = filtertype;
                this.dispatchEvent( fse );*/
                facade.sendNotification(ApplicationFacade.FILTER_SELECTED, filtertype);
                _httpservice = new HTTPService();
               _httpservice.url = "/inventory/map_filter_selected";
               _httpservice.method = "GET";
               _httpservice.useProxy = false;
               _httpservice.addEventListener( ResultEvent.RESULT, incrementFilterClickedStatsResult );
               _httpservice.addEventListener( FaultEvent.FAULT, incrementFilterClickedStatsFault );
             }
             
            public function onLaunchOpeningInfo():void {
                facade.sendNotification( ApplicationFacade.SHOW_OPENING_INFO_PANEL );
            }
           
            public function onRefreshTheData() : void
            {
               facade.sendNotification( ApplicationFacade.EXTINT_CALLS_DATAREFRESH );
            }
           
            public function onSwitchMode( modetype:String ):void {
               sendNotification( ApplicationFacade.SWICH_GRAPH_MODE, modetype );
            }
             
            public function onSwitchViews( newview:String ):void {
                //TODO: this should probably be a case statement incase we have more than 2 views.
                facade.sendNotification( ApplicationFacade.SWICH_GRAPH_LAYOUT, newview );
                facade.sendNotification( ApplicationFacade.SCROLL_HOME_NAVCIRCLE, newview );
            }
           
              
      private function incrementFilterClickedStatsResult(event:ResultEvent):void{
            trace( 'Result: increment filter clicked stat successful');
            _httpservice.removeEventListener( ResultEvent.RESULT, incrementFilterClickedStatsResult );
            _httpservice.removeEventListener( FaultEvent.FAULT, incrementFilterClickedStatsFault );
        }
        private function incrementFilterClickedStatsFault(event:FaultEvent):void{
            trace( 'Fault: increment filter clicked stat fault' + event);
            _httpservice.removeEventListener( ResultEvent.RESULT, incrementFilterClickedStatsResult );
            _httpservice.removeEventListener( FaultEvent.FAULT, incrementFilterClickedStatsFault );
        }
      
      
      override public function listNotificationInterests():Array
      {
         return [
              ApplicationFacade.GRAPHCHANGED
         
          ];
      }
      
      override public function handleNotification(notification:INotification):void
      {
         if (ExternalInterface.available) {
            switch ( notification.getName() )
            {
               case ApplicationFacade.GRAPHCHANGED:
                   ExternalInterface.call("MyMap.filtersReady", notification.getBody as Array);
                   break;
                 default : break;
            }
         }   
      }
      
   }

Thanks for any help.