从Javascript调用Flex / AS3回调

时间:2009-09-28 00:08:25

标签: javascript flex actionscript-3 callback

我有一个Javascript API,它可以与GWT和Flex一起使用。使用FABridge,从AS3调用Javascript方法非常容易,反之亦然。但是当我尝试在我的Javascript API中向AS3方法注册回调时,我遇到了困难。这是一个简短的代码示例:

public function initApp():void {
    if (ExternalInterface.available) { 
        ExternalInterface.addCallback("foobar", foobar);
}
}

public function foobar():void {
    //the callback function
    Alert.show("Callback from API works!");
}

private function btnCallbackClicked():void {
    ExternalInterface.call("testAPICallbackFromJS", Application.application.foobar);
}

简单的JS方法:

function testAPICallbackFromGWT(callback){
  $clinit_26(); //added by the GWT compiler
  alert('callback to be launched 3 2 1');
  callback();
}

但是这个版本不起作用,因为我总是在我的JS代码中收到一个空函数。似乎FABridge正在削减其余部分。 然后我尝试了另一种方法。我写了一个小JS方法,它接受函数的名称并从JS端创建回调。

registerFlexCallback = function(registerMethod, callback, id) {
    /*
    workaround to create a callback for an AS method, which can be called by Javascript
        * registerMethod - Javascript method which shall be called for registration with the created callback as parameter
        * callback - AS method that shall be called by Javascript (available over the FABridge interface)
        * id - ID of the flash object (use Application.application.id in AS)
    */
    var swf = document.getElementById(id);
    eval(registerMethod + "(swf." + callback + ");");
};

这个适用于Internet Explorer,但没有其他浏览器。例如在Firefox中我收到以下错误消息:

NPMethod called on non-NPObject wrapped JSObject!

有人可以告诉我,这个错误是什么(可能是某种安全问题)?或者有没有人更好地了解如何为我的AS3方法创建可以由JS调用的回调?

2 个答案:

答案 0 :(得分:2)

这是因为函数不会在FABridge上进行序列化。

中的含义
ExternalInterface.call("testAPICallbackFromJS", Application.application.foobar);

第二个参数将始终为null。我所做的是在HTML页面上添加一个包装方法,通过eval指向我的嵌入,因此添加了回调。所以你必须添加一个额外的,但烦人的步骤:

ExternalInterface.addCallback("foobar", foobar);

var callBack:String = "";
var functionName:String = UIDUtil.createUUID; 
callBack = "function " + functionName + "( ){ " + 
"document.getElementById('applicationName').foobar(arguments);"+
"}";
ExternalInterface.call("eval", callback);


ExternalInterface.call("testAPICallbackFromJS", functionName);

您看到的NPObject错误我很确定是一个安全错误(基于它来自FF代码的位置)可能会阻止您动态注入可以在没有JS解释器进入的情况下进行评估的方法方式。

我甚至没有尝试过编译上面的内容,希望你能得到主旨。

答案 1 :(得分:1)

我马上注意到两件事

首先,如果ExternalInterface没有准备好,你的ExternalInterface会死掉。

public function initApp():void {
   if (ExternalInterface.available) { 
    ExternalInterface.addCallback("foobar", foobar);
}
}

我会添加一个timout然后重试,以便它再次尝试,直到Externalinterface准备就绪。

此外,我在您的javascript代码中看不到“foobar”功能。我看到回调作为一个变量传入,但没有变化它实际上是'foobar'这是一种可以使测试成为一个错误的事件。

function testAPICallbackFromGWT(callback){
  $clinit_26(); //added by the GWT compiler
  alert('callback to be launched 3 2 1');
  callback();
}

我会简化您的测试示例,以便减少移动部件。

// e.g. run just flash to javascript only
ExternalInterface.call("alert", "hello out there");

如果有效

// establish the call from flash
ExternalInterface.addCallback("hello_out_there", foobar);

// and in javascript
alert(typeof('hello_out_there')); // will be 'function' if exists or undefined if ExternalInterface did not work

通过这种方式,您可以获得一些工作位和工作位置。

请注意时间,如果您可以从按钮操作中触发闪光灯,并且从链接中获取javascript也可以消除许多加载问题。当然,你需要为你的发布解决自动加载版本,但是测试手动触发的事件可以大大简化事情。

也因为它是javascript浏览器是相关的。

我在Firefox和Internet Explorer中看到了一致的结果,在safari中分解,有时IE浏览器是奇怪的。

有时Firefox是唯一一个破解的人。

你只需要测试它们。