Queue ExternalInterface调用UpdatePanel中的Flash对象 - 需要改进吗?

时间:2010-06-09 04:32:11

标签: javascript flash updatepanel closures externalinterface

使用embedCallAC_FL_RunContent.js脚本的修改版本在Update Panel中的ASP.Net页面上创建Flash(实际上是Flex)对象,以便可以动态编写。使用此脚本重新创建它,每个部分回发到该面板。页面上还有其他更新面板。

使用一些回发(部分和完整),外部接口调用(如$get('FlashObj').ExternalInterfaceFunc('arg1', 0, true);)在服务器端准备,并使用ScriptManager.RegisterStartupScript添加到页面中。它们嵌入在函数中,并填充到Sys.Application的加载事件中,例如Sys.Application.add_load(funcContainingExternalInterfaceCalls)

问题在于,因为Flash对象的状态可能随着每个部分回发而改变,所以当JavaScript - >时,Flash(Flex)对象和/或外部接口可能还没有准备好,甚至还没有存在于DOM中。进行Flash外部接口调用。它会导致“对象不支持此属性或方法”异常。

我有一个工作策略是在Flash准备就绪时立即调用ExternalInterface,或者将它们排队,直到Flash宣布其准备就绪为止。

//Called when the Flash object is initialized and can accept ExternalInterfaceCalls
var flashReady = false;
//Called by Flash when object is fully initialized
function setFlashReady() {
    flashReady = true;
    //Make any queued ExternalInterface calls, then dequeue
    while (extIntQueue.length > 0)
        (extIntQueue.shift())();   
}
var extIntQueue = [];
function callExternalInterface(flashObjName, funcName, args) {
    //reference to the wrapped ExternalInterface Call
    var wrapped = extWrap(flashObjName, funcName, args);
    //only procede with ExternalInterface call if the global flashReady variable has been set
    if (flashReady) {
        wrapped();
    }
    else {
        //queue the function so when flashReady() is called next, the function is called and the aruments are passed.
        extIntQueue.push(wrapped);
    }
}
//bundle ExtInt call and hold variables in a closure
function extWrap(flashObjName, funcName, args) {
        //put vars in closure
        return function() {
            var funcCall = '$get("' + flashObjName + '").' + funcName;
            eval(funcCall).apply(this, args);
        }
    }

每当我更新包含Flash(Flex)对象的更新面板时,我都会将flashReady var设置为脏。

ScriptManager.RegisterClientScriptBlock(parentContainer, parentContainer.GetType(), "flashReady", "flashReady = false;", true);

我很高兴我得到它的工作,但感觉就像一个黑客。关于闭包这样的概念,我仍处于学习曲线上,为什么“eval()”显然是邪恶的,所以我想知道我是否违反了一些最佳实践,或者是否应该改进这些代码,如果是这样的话?感谢。

1 个答案:

答案 0 :(得分:0)

不幸的是,我必须做一些与你正在做的非常类似的变通办法,包括检查以确保Flash已准备好接受呼叫,然后排队命令。

一个众所周知的问题是,快速连续调用多个ExternalInterface调用(相隔大约400毫秒)可能会导致一些被忽略或丢弃。

我感觉到你的痛苦!