我有一个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调用的回调?
答案 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是唯一一个破解的人。
你只需要测试它们。