Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Over 10 years of community discussion and knowledge are maintained here as a read-only archive.

New discussions should be taken up in issues on the appropriate projects at https://github.com/PureMVC

Pages: [1]
Print
Author Topic: Using PureMVC and the ExternalInterface  (Read 9343 times)
ArgV
Newbie
*
Posts: 1


View Profile Email
« 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
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #1 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>
Logged
trilec
Sr. Member
****
Posts: 52



View Profile WWW Email
« Reply #2 on: March 18, 2008, 06:02:03 »

also an approch for deep linking..ie SWFAddress?

Logged
jgervin
Courseware Beta
Sr. Member
***
Posts: 50


View Profile Email
« Reply #3 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.
Logged
Pages: [1]
Print