最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Calling a FlexAS3 Callback from Javascript - Stack Overflow

programmeradmin2浏览0评论

I have a Javascript API, which should be usable with GWT and Flex. Using the FABridge it is really easy to call Javascript methods from AS3 and vice versa. But when I try to register a callback to an AS3 method in my Javascript API I get stuck. Here is a short code sample:

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);
}

And the simple JS method:

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

But this version does not work, because I always receive an empty function in my JS code. It seems that the FABridge is cutting the rest. Then I tried a different approach. I wrote a little JS method, which takes the name of the function and creates the callback from the JS side.

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 + ");");
};

This one works well with the Internet Explorer, but with no other browser. For example in Firefox I get the following error message:

NPMethod called on non-NPObject wrapped JSObject!

Can somebody tell me, what this error is about (maybe some kind of security issue)? Or does anyone have a better idea how to create callbacks for my AS3 methods which can be called by JS?

I have a Javascript API, which should be usable with GWT and Flex. Using the FABridge it is really easy to call Javascript methods from AS3 and vice versa. But when I try to register a callback to an AS3 method in my Javascript API I get stuck. Here is a short code sample:

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);
}

And the simple JS method:

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

But this version does not work, because I always receive an empty function in my JS code. It seems that the FABridge is cutting the rest. Then I tried a different approach. I wrote a little JS method, which takes the name of the function and creates the callback from the JS side.

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 + ");");
};

This one works well with the Internet Explorer, but with no other browser. For example in Firefox I get the following error message:

NPMethod called on non-NPObject wrapped JSObject!

Can somebody tell me, what this error is about (maybe some kind of security issue)? Or does anyone have a better idea how to create callbacks for my AS3 methods which can be called by JS?

Share Improve this question asked Sep 28, 2009 at 0:08 SilentGertSilentGert 532 silver badges4 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 2

This is because functions don't serialize across the FABridge. Meaning in your

ExternalInterface.call("testAPICallbackFromJS", Application.application.foobar);

the second parameter will always be null. What I do is add a wrapper method on the HTML page via eval that points at my embed and therefore the added callback. So you have to add an extra, while annoying step:

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);

The NPObject error you're seeing I'm pretty sure is a security error ( based on where it es from in the FF code ) probably preventing you from dynamically injecting methods that can be eval'ed without the JS interpreter getting in the way.

I haven't even tried to pile the above so, hopefully you get the gist.

I notice two things right away

firstly it appears your ExternalInterface will die if the ExternalInterface is not ready.

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

I would add a timout and then try again so that it tries again until Externalinterface is ready.

Also I don't see the function "foobar" in your javascript code. I see callback passed in as a variable but without varifying that it is in fact 'foobar' this is hte kind of thing that can make testing a misserable event.

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

I would simplify your testing example so that there are less moving parts.

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

if that works

// 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

This way you can get a handle bit for bit what is working and where it breaks down.

Pay atention to the timing, if you can tigger your flash from button actions and your javascript from links you can illiminate a number of loading issues as well. of course you'll need to solve an autoload version for your launch but for testing manually triggered events can simplify things significantly.

also because it's javascript the browser is relevant.

I've seen consistent results in Firefox and Internet explorer that break down in safari and sometimes IE is the odd browser out.

Sometimes Firefox is the only one that breaks.

you just have to test them all.

发布评论

评论列表(0)

  1. 暂无评论