2011-10-17 30 views
0

正在構建AIR桌面應用程序。一次,應用程序加載一個彈出窗口(基於s:Window的MXML組件),其中包含加載本地(在應用程序目錄中)html文件的mx:HTML組件,blank.html。在blank.html相關要素是:使用參數中的複雜對象從AS3調用JS函數

<script src="jw/jwplayer.js"/> <!--JW Player's JS-based Embedder--> 
... 
<div id="jwtarget" /> <!-- the target that the embedder will use --> 

因爲我想用在運行時確定的參數,我用的是domWindow屬性來調用它加載播放機的方法。下面是工作的例子:

private function injectPlayer():void { 
    var playerVars:Object = {}; 
    playerVars.flashplayer = "jw/player.swf"; 
    playerVars.file = "http://www.archive.org/download/meet_john_doe_ipod/meet_john_doe_512kb.mp4"; 
    playerVars.height = 360; 
    playerVars.width = 640; 

    try { // attempt to invoke the js function 
    htmlComponent.domWindow.jwplayer("jwtarget").setup(playerVars); 
    } catch(e:Error) {} 

} 

,當頁面完成通過加載被稱爲:

<mx:HTML id="htmlComponent" location="assets/blank.html" complete="injectPlayer()" /> 

這一切工作正常。

現在的問題。我需要能夠將更復雜的playerVars對象傳遞給函數,但我似乎沒有得到正確的語法。這是我一直試圖的最簡單的例子:

private function injectPlayer():void { 
    var playerVars:Object = {}; 
    //playerVars.flashplayer = "jw/player.swf"; 
    playerVars.file = "http://www.archive.org/download/meet_john_doe_ipod/meet_john_doe_512kb.mp4"; 
    playerVars.height = 360; 
    playerVars.width = 640; 
    playerVars.modes = [{"type":"flash","src":"jw/player.swf"}]; 

    try { // attempt to invoke the js function 
    htmlComponent.domWindow.jwplayer("jwtarget").setup(playerVars); 
    } catch(e:Error) {} 

} 

此代碼應該創建與上面的代碼完全相同的內容,但它無法執行。我假設我需要以某種方式更改語法,以便將對象數組(modes)作爲參數正確傳遞給js函數。

我已經嘗試了各種各樣的東西,比如通過modes作爲字符串,或者首先通過JSON.stringify()整個事情,但無濟於事。任何人都知道爲參數構造複雜對象的正確方法嗎?其他細節,如果您現在還沒有推斷出它們:Flex 4.5.1是我正在構建的SDK,包括AIR 3.0擴展(這意味着針對FP11)。

更新:

另一個配置我想,這不工作:

playerVars.modes = {"type":"flash", "src":"jw/player.swf"}; 

然而,這仍然沒有解決,我應該能夠傳遞對象的數組中的問題modes屬性。但至少這種方式加載視頻播放器。

更多更新:

所以,我發現這個代碼小部分來自jwplayer.js,我懷疑玩家加載是失敗:

if (typeof parsedConfig.modes == "string") { 
    _modes = _playerDefaults(); 
    _modes[0].src = parsedConfig.modes; 
} else if (parsedConfig.modes instanceof Array) { // I suspect this was eval'd as false 
    _modes = parsedConfig.modes; 
} else if (typeof parsedConfig.modes == "object" && parsedConfig.modes.type) { 
    _modes = [parsedConfig.modes]; 
} 

,並測試我懷疑我將下列功能添加到我的空白處。HTML

<script type="text/javascript"> 
    var instanceOfArrayTest = function(arr) { 
    return arr instanceof Array; 
    } 
</script> 

在我的ActionScript代碼試過如下:

trace([1,2,3] is Array); // true 
trace(htmlComponent.domWindow.instanceOfArrayTest([1,2,3])); // false!!!! 

所以,看來問題是,ActionScript中不流通AS3數組對象作爲JS數組對象!

+0

playerVars.modes = [{「type」:「flash」}];這應該是一個數組與第一個元素的對象? –

+0

@The_asMan - 是的。通常會包含其他可能的模式,也作爲對象,例如。 '[{「type」:「flash」,「src」:「player.swf」},{「type」:「html5」},{「type」:「download」}]',可能的後備。希望最初發布這個問題時我忘記了''src「:」player.swf「這個事實並沒有讓你失望。我一經注意就修改了它。 – merv

+0

對我來說,這似乎很奇怪,參數是一個對象數組,但對象只有一個屬性。這一切都可以在一個對象或關聯數組上完成。我願意打賭它沒有正確設置 –

回答

1

不像ExternalInterface類的call()方法,對MX:HTML不會自動AS3類轉換成相應的JS類時,他們作爲參數傳遞給一個JS函數傳遞。相反,HTML Control維護一個環境,在該環境中AS3類本地的方法和屬性被保留並直接被JS訪問。

如果JS函數需要JS Array對象,則必須使用JavaScript Window對象明確創建JS Array才能訪問JS Array構造函數。 HTML控件通過它的domWindow屬性提供對此的訪問。否則,沒有辦法將AS3陣列「投射」到JS陣列。

這裏有一個基本的例子:

var JSArray:Function = htmlComponent.domWindow.Array; 
htmlComponent.domWindow.instanceOfArrayTest(JSArray(1,2,3)); // true 

而對於使用JW播放器的配置參數的更復雜的例子:

playerVars.modes = JSArray({"type":"flash","src":"jw/player.swf"},{"type":"html5"}); 

它創建了兩個對象的JS數組。

有關HTML控件中JavaScript環境的更多信息,請查看Adobe的JavaScript in AIR部分使用Flex開發AIR應用程序

2

嘗試這樣做,而不是:

playerVars.modes = [{type:"flash",src:"jw/player.swf"}]; 
+0

感謝您的建議@J_A_X。這並沒有解決問題,但是從我的測試來看,它和我放入的初始表單一樣有效。也就是說,這個語法和我使用的_appear_在JS對象中正確解析的語法函數返回。我開始認爲,問題的根源可能不同。 :( – merv