0

Flash (実際には Flex) オブジェクトは、動的に書き込むことができるように、embedCallAC_FL_RunContent.js スクリプトの修正バージョンを使用して更新パネル内の ASP.Net ページに作成されます。そのパネルへの部分的なポストバックごとに、このスクリプトで再作成されます。ページには他の更新パネルもあります。

一部のポストバック (部分的および完全) では、などの外部インターフェイス呼び出し$get('FlashObj').ExternalInterfaceFunc('arg1', 0, true);がサーバー側で準備され、ScriptManager.RegisterStartupScript を使用してページに追加されます。それらは関数に埋め込まれ、Sys.Application の load イベントに詰め込まれますSys.Application.add_load(funcContainingExternalInterfaceCalls)

問題は、部分的なポストバックごとに Flash オブジェクトの状態が変化する可能性があるため、JavaScript -> Flash 外部インターフェイスの呼び出しが行われたときに、Flash (Flex) オブジェクトおよび/または外部インターフェイスの準備ができていないか、DOM にまだ存在していない可能性があることです。 . 「オブジェクトはこのプロパティまたはメソッドをサポートしていません」という例外が発生します。

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 変数をダーティに設定します。

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

私はそれが機能したことをうれしく思いますが、それはハックのように感じます. 「eval()」が明らかに悪い理由であるクロージャーのような概念に関して、私はまだ学習曲線にあるので、ベストプラクティスに違反しているのか、それともこのコードを改善する必要があるのか​​ 疑問に思っています。ありがとう。

4

1 に答える 1

0

残念ながら、私はあなたがしていることと非常によく似た回避策を取らなければなりませんでした.Flashが呼び出しを受け入れる準備ができていることを確認してから、コマンドをキューに入れます.

複数の ExternalInterface 呼び出しを立て続けに (約 400 ミリ秒間隔で) 呼び出すと、一部が無視されるかドロップされる可能性があるという既知の問題があります。

あなたの痛みが分かります!

于 2010-06-10T18:56:30.477 に答える