与Flash CS3中的Flex App交互

时间:2011-03-15 10:26:39

标签: flash flex actionscript-3

我在Flash中有一个全景查看器,我想在其中嵌入一个小型Flex应用程序。我设法将Flex swf加载到Flash中,如下所示:

private var loader:Loader = new Loader();

var req:URLRequest = new URLRequest("SimpleImageViewer.swf");
loader.load(req);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, imgViewerLoaded);

imgViewerLoaded(event:Event)
{
    imageViewer = loader.content;
    addChild(imageViewer);
    imageViewer.showImage("test.jpg", "Test Image");
}

现在,问题是我需要能够在imageViewer上调用一个方法,我在我的Flex App中定义了这样一个方法:

public function showImage(source:String, heading:String = ""):void
{
    //Show the image
}

它也使用

添加到ExternalInterface
ExternalInterface.addCallback("showImage", showImage);

如何从AS3 Flash调用该方法?只需将其称为imageViewer.showImage(...)就会出现此错误:

  

ReferenceError:错误#1069:在_SimpleImageViewer_mx_managers_SystemManager上找不到属性showImage,并且没有默认值。

     

在UserInterface / imgViewerLoaded()

这是整个SimpleImageViewer.mxml文件:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" minWidth="100" minHeight="100" backgroundColor="#2B2B2B" creationComplete="onCreationComplete(event)" backgroundGradientAlphas="[1.0, 1.0]" backgroundGradientColors="[#2B2B2B, #2B2B2B]" verticalScrollPolicy="off" horizontalScrollPolicy="off">
<mx:Image x="0" y="0" width="100%" height="100%" horizontalAlign="center" verticalAlign="middle" scaleContent="true" maintainAspectRatio="true" id="picture"/>
<mx:Image width="100%" height="42" x="0" y="0" id="headingBg" source="@Embed(source='/bilder/topList.png')" scaleContent="true" maintainAspectRatio="false"/>
<mx:Label x="4" y="0" width="100%" height="43" id="headingTxt" fontFamily="Arial" fontSize="32" color="#FFFFFF" textAlign="center"/>

<mx:Script>
    <![CDATA[
        import mx.events.FlexEvent;
        import mx.events.ResizeEvent;

        public function showImage(source:String, heading:String = ""):void
        {
            picture.source = source;
            picture.load();
            headingTxt.text = heading;
        }

        protected function onCreationComplete(event:FlexEvent):void
        {               
            ExternalInterface.addCallback("showImage", showImage);
            Security.allowDomain("localhost");
        }


    ]]>
</mx:Script>
</mx:Application>

和ImageViewer界面:

package tikab.lizzan
{
    public interface ImageViewer
    {
        function showImage(source:String, heading:String = ""):void ;   
    }
}

3 个答案:

答案 0 :(得分:2)

编辑:

来自flex文档:

  

如果加载了应用程序   另一个应用程序,一个SystemManager   仍将被创建,但不会   管理应用程序窗口,   取决于安全性和域名   规则。相反,它将是内容   加载它的Loader和   只是作为的父母   子应用程序

换句话说:当您将Flex应用程序加载到另一个应用程序时,加载程序对象的content属性不会直接指向应用程序本身,而是指向SystemManager实例,该实例充当该应用程序的父实例。实际的Application对象。因此,您的方法调用必须指向loader.content.getChildAt(0)

以类型安全的方式执行此操作:

  1. 创建界面
  2. 让您的flex文档类实现它
  3. 将Loader对象内容的第一个Child强制转换为同一个界面
  4. 或者(不是类型安全的,但很快)只需使用括号语法调用该方法:

    loader.content.getChildAt(0)["showImage"]();
    

    或将loader.content.getChildAt(0)转换为动态类型,如Object或MovieClip,如@_asMan推荐。

    编辑:

    您在代码中也遗漏了一些重要的声明语句。这就是imageViewerLoaded函数的样子:

    function imgViewerLoaded(event:Event)
    {
        var imgViewer:MovieClip = loader.content.getChildAt(0) as MovieClip;
        addChild(loader.content);
        imgViewer.showImage("test.jpg", "Test Image");
    }
    

    functionvar 永远不会被认为是可选的 - 它们可以帮助您防止搞乱您的类层次结构并输入引用。 (如果你在其他地方将var声明为成员变量,你可以省略imgViewer我也改变了“imageViewer”的名称以确保没有含糊不清的引用 - 你发布的错误声明以下意味着风险;)

答案 1 :(得分:0)

编辑#2:

试试这个:

function imgViewerLoaded(event:Event):void
{
    var manager:SystemManager = event.target.content as SystemManager;
    var content:ImageViewer = manager.application as ImageViewer;
    addChild(viewer);
    viewer.showImage();
}

这建立在weltraumpirat的有用见解之上,即内容类型实际上是一个SystemManager对象。根据我看到的一切,我认为这将有效并且更清洁。祝你好运!

**当然,请注意您必须修改已发布的MXML以实现您的界面,因为我怀疑您已经完成了

编辑#1:


根据您上面的消息,我发现我的一些代码执行相同的操作:

private function loadCompleted(event:Event):void {
        currentClip = event.target.content as MovieClip;
        loader.unload();
        displayClip();
}

所以你可能还想尝试查看以下内容:

event.target.content

尝试使用以下代码查看类型,然后使用该信息进行投射:

var contents:* = event.target.content;
var className:String = flash.utils.getQualifiedClassName( contents );
trace("Class name was: " + className);

从那里,您可以使用以下代码中的代码更清晰地访问该方法:

function imgViewerLoaded(event:Event):void
{
    var viewer:TypeThatYouFound = loader.content as TypeThatYouFound;
    addChild(viewer);
    viewer.showImage();
}

当然,事实上,事件内容可能与Loader内容完全相同。在这种情况下,这种方法不会明显更好。但是,值得一试。

希望在某种程度上有所帮助,

〜gMale


确定。所以我甚至不会问你为什么要反向做这件事(通常情况下,你从flash转到flex而不是反过来。将swfs导入Flex而不是Flex导入SWF是很常见的。)

首先想到的是,您可能没有为Flex代码创建类。要公开你的函数,你必须让别人知道你的对象与典型的SimpleImageViewer不同。

根据您的设计方式,您可能需要制作一个自定义类,如

public class MySimpleImageViewer extends SimpleImageViewer {
        public function showImage(source:String, heading:String = ""):void {
            //Show the image
        }
}

然后让您的MXML文件使用以下语法对其进行实例化:

<local:MySimpleImageViewer />

由于你的方法有点不正统,很难说,正是你所需要的。如果这没有帮助,请尝试发布您的Flex代码,我们可以从那里开始......

希望有所帮助,

〜gMale

答案 2 :(得分:0)

不确定这会有效,但是,您是否尝试将其作为对象?

imgViewerLoaded(event:Event)
{
    imageViewer = loader.content;
    addChild(imageViewer);
    Object( loader.content ).showImage();
}

或者如果已经分配了一个,则可能作为基类。我用Application作为例子

var loadedApp:Application = Application( loader.content );
loadedApp.showImage();