开发者

Call an Adobe Flex/ActionScript method from JavaScript?

开发者 https://www.devze.com 2023-04-06 14:56 出处:网络
I need to know why JavaScript can\'t talk back to Flex. I have a project that is going to use JavaScript to play a given video file. Its running on a custom MVC framework where asset files are loaded

I need to know why JavaScript can't talk back to Flex. I have a project that is going to use JavaScript to play a given video file. Its running on a custom MVC framework where asset files are loaded via the /static prefix.

Example: http://helloworld/static/swf/movie.swf`

I compile my Flex application using the mxmlc binary with options -static-link-runtime-shared-libraries=true, -use-network=true and --debug=true.

Flex

<?xml version="1.0" encoding="utf-8"?>
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    creationComplete="init()">
    <fx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import flash.external.ExternalInterface;
            private function init():void {
                log("Logging...");
                if (ExternalInterface.available) {
                    ExternalInterface.call("HelloWorld.initFlash");
                    ExternalInterface.addCallback("playVideo", playVideo);
                }
            }
            public function playVideo():void {
                log("Playing video...");
            }
            public function log(message:String):void {
                if (ExternalInterface.available) {
                    ExternalInterface.call(
                        "function log(msg){ if (window.console) { console.log(msg); } }", 
                        message);
                }
            }
        ]]>
    </fx:Script>
    <s:Panel id="myPanel" title="Hello World" x="20" y="20">
        <s:layout>
            <s:HorizontalLayout 
                paddingLeft="10"
                paddingRight="10"
                paddingTop="10"
                paddingBottom="10"
                gap="5" />
        </s:layout>       
    </s:Panel>
</s:Application>

HTML

<!DOCTYPE HTML>
<html lang="en-US">
    <head>
        <meta charset="UTF-8">
        <title>Hello World</title>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
        <script type="text/javascript">
            $(function(){
                var swfVersionStr        = "10.1.0";
                var xiSwfUrlStr          = "playerProductInstall.swf";
                var flashvars            = {};
                var params               = {};
                var attributes           = {};
                params.allowscriptaccess = "sameDomain";
                params.quality           = "high";
                params.bgcolor           = "#FFFFFF";
                params.allowfullscreen   = "true";
                attributes.id            = "HelloWorld";
                attributes.name          = "HelloWorld";
                attributes.align         = "left";
                swfobject.embedSWF( 
                    "HelloWorld.swf", 
                    "flash-content", 
                    "100%", "100%", 
                    swfVersionStr, xiSwfUrlStr, flashvars, params, attributes ); 
                HelloWorld = function(){
                    return {
                        initFlash : function() {
                            console.log("Called from Flex...");开发者_开发问答
                            console.log($("#HelloWorld").get(0).playVideo("be6336f9-280a-4b1f-a6bc-78246128259d"));
                        }
                    }
                }();
            });
        </script>
        <style type="text/css">
            #flash-content-container {
                width  : 400px;
                height : 300px;
            }
        </style>
    </head>
    <body>
        <div id="layout">
            <div id="header"><h1>Hello World</h1></div>
            <div id="flash-content-container">
                <div id="flash-content"></div>
            </div>
        </div>
    </body>
</html>

Output

Logging...
Called from Flex...


I had the same issue, in the link provided by Chris Cashwell it shows the base for the solution.

Flex MXML

    <?xml version="1.0" encoding="utf-8"?>
    <s:Application 
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx"
        creationComplete="init()">
        <fx:Script>
            <![CDATA[
                import mx.controls.Alert;
                import flash.external.ExternalInterface;
                private function init():void {
                    consoleLog("Hello World");
                    try 
                    {  
                        Security.allowDomain("*"); //I need to add this.
                        ExternalInterface.marshallExceptions = true;
                        ExternalInterface.addCallback("sendAlert",sendAlert);
                        ExternalInterface.call("initCallBack");
                    }  catch (error:Error) {
                        consoleLog("Error in ExternalInterface");                           
                        consoleLog("Error" + error.message);
                    }
                }
                public function sendAlert(s:String):void
                {
                    Alert.show(s);
                }
                public function consoleLog(message:String):void {
                    if (ExternalInterface.available) {
                        ExternalInterface.call(
                            "function log(msg){ if (window.console) { console.log(msg); } }", 
message);
                    }
                }
            ]]>
        </fx:Script>
        <s:Panel id="panel1" title="Hello World" x="20" y="20">
            <s:layout>
                <s:HorizontalLayout 
                    paddingLeft="10"
                    paddingRight="10"
                    paddingTop="10"
                    paddingBottom="10"
                    gap="5" />
            </s:layout>
            <s:TextArea id="textarea1" 
                width="300" height="100" 
                text="Hello World" />       
        </s:Panel>
    </s:Application>

HTML

<!DOCTYPE HTML>
<html lang="en-US">
    <head>
        <meta charset="UTF-8">
        <title>Hello World</title>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
        <script type="text/javascript">
            var flexApp;
            function initCallBack() {  
                flexApp = document.getElementById("HelloWorldFlex");
                if (flexApp != undefined) { 
                   try {
                      flexApp.sendAlert( "Hello World" );
                   } catch(err) {
                      console.log("There was an error on the flex callback.");
                      console.log(err);     
                   }
                } else {
                    console.log("The flex object does not exist yet");
                }
                return;
            } 
            $(function(){
                HelloWorld = function(){
                    return {
                        init : function() {
                            var swfVersionStr        = "10.1.0";
                            var xiSwfUrlStr          = "playerProductInstall.swf";
                            var flashvars            = {
                                bridgeName : "flex",
                            };
                            var params               = {};
                            var attributes           = {};
                            params.allowscriptaccess = "always";
                            params.quality           = "high";
                            params.bgcolor           = "#FFFFFF";
                            params.allowfullscreen   = "true";
                            attributes.id            = "HelloWorldFlex";
                            attributes.name          = "HelloWorldFlex";
                            attributes.align         = "left";
                            swfobject.embedSWF( 
                                "HelloWorld.swf", 
                                "flash-content", 
                                "100%", "100%", 
                                swfVersionStr, xiSwfUrlStr, flashvars, params, attributes ); 

                        }
                    }
                }();
                HelloWorld.init();
            });
        </script>
        <style type="text/css">
            #flash-content-container {
                width  : 400px;
                height : 300px;
            }
        </style>
    </head>
    <body>
        <div id="layout">
            <div id="header"><h1>Hello World</h1></div>
            <div id="flash-content-container">
                <div id="flash-content"></div>
            </div>
        </div>
    </body>

I tested it on Flex 4.1, please notice that i had to add the bin-debug folder (C:\flexworkspaces\project\bin-debug) to the flash security app ( http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.htmlconfiguration ) Please notice that this internet URL is in fact an app that modifies the Flex local configuration.

The logs can be displayed in the Firebug console.


Decided to go with FABridge. For others heres a working example.

MXML

<?xml version="1.0" encoding="utf-8"?>
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:bridge="bridge.*"
    creationComplete="init()">
    <fx:Declarations>
        <bridge:FABridge bridgeName="flex" />
    </fx:Declarations> 
    <fx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import flash.external.ExternalInterface;
            private function init():void {
                consoleLog("Hello World");
            }
            public function sendAlert(s:String):void
            {
                Alert.show(s);
            }
            public function consoleLog(message:String):void {
                if (ExternalInterface.available) {
                    ExternalInterface.call(
                        "function log(msg){ if (window.console) { console.log(msg); } }", 
                        message);
                }
            }
        ]]>
    </fx:Script>
    <s:Panel id="panel1" title="Hello World" x="20" y="20">
        <s:layout>
            <s:HorizontalLayout 
                paddingLeft="10"
                paddingRight="10"
                paddingTop="10"
                paddingBottom="10"
                gap="5" />
        </s:layout>
        <s:TextArea id="textarea1" 
            width="300" height="100" 
            text="Hello World" />       
    </s:Panel>
</s:Application>

HTML

<!DOCTYPE HTML>
<html lang="en-US">
    <head>
        <meta charset="UTF-8">
        <title>Hello World</title>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
        <script type="text/javascript" src="bridge/FABridge.js"></script>
        <script type="text/javascript">
            var flexApp;
            var initCallback = function() {  
                flexApp = FABridge.flex.root();  
                var textarea1 = flexApp.getTextarea1();
                textarea1.setText( "Hello World (Updated)" );
                flexApp.sendAlert( "Hello World" );
                return;
            } 
            $(function(){
                HelloWorld = function(){
                    return {
                        init : function() {
                            var swfVersionStr        = "10.1.0";
                            var xiSwfUrlStr          = "playerProductInstall.swf";
                            var flashvars            = {
                                bridgeName : "flex",
                            };
                            var params               = {};
                            var attributes           = {};
                            params.allowscriptaccess = "sameDomain";
                            params.quality           = "high";
                            params.bgcolor           = "#FFFFFF";
                            params.allowfullscreen   = "true";
                            attributes.id            = "HelloWorld";
                            attributes.name          = "HelloWorld";
                            attributes.align         = "left";
                            swfobject.embedSWF( 
                                "HelloWorld.swf", 
                                "flash-content", 
                                "100%", "100%", 
                                swfVersionStr, xiSwfUrlStr, flashvars, params, attributes ); 
                            FABridge.addInitializationCallback( "flex", initCallback );
                        }
                    }
                }();
                HelloWorld.init();
            });
        </script>
        <style type="text/css">
            #flash-content-container {
                width  : 400px;
                height : 300px;
            }
        </style>
    </head>
    <body>
        <div id="layout">
            <div id="header"><h1>Hello World</h1></div>
            <div id="flash-content-container">
                <div id="flash-content"></div>
            </div>
        </div>
    </body>
</html>
0

精彩评论

暂无评论...
验证码 换一张
取 消