
Flex로 개발을 하다보면 내부 액션스크립트뿐만 아니라 자바스크립트로 기능을 확장할 필요가 있다. 브라우저의 input 값을 읽어오거나 Flex의 입력값을 외부로 내보내는 등 통신이 필요하기 때문이다.
Flex에서는 이처럼 위부 API와의 통신을위해, ExternalInterface 클래스를 재공한다.
아래의 코드는 Flex와 JavaScript간의 통신을 하는 예이다.
Flex코드 (Demo.mxml)
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
initialize="initApp()">
<mx:Script>
<![CDATA[
private var isAvailable:Boolean = false;
private function showPopup():void
{
mx.controls.Alert.show(txtFxMsg.text);
}
private function jsAlter():void
{
// 외부 인터페이스를 사용할 수 있다면..
if (isAvailable)
{
// 외부 인터페이스(HTML)의 자바스크립트를 호출한다.
ExternalInterface.call("jsAlter", txtJsMsg.text);
}
else
{
mx.controls.Alert.show(txtJsMsg.text);
}
}
private function initApp():void
{
// 외부 인터페이스를 갖춘 컨테이너에 포함되어있는지 여부를 나타낸다.
isAvailable = ExternalInterface.available;
if (isAvailable)
{
// 컨테이너로부터 호출할 수 있도록 등록한다.
// 호출에 성공하면, JavaScript로부터 호출할 수 있다.
ExternalInterface.addCallback("flexFunc", innerHTML);
}
}
private function innerHTML():void
{
if (isAvailable)
{
var txtMsg:String = ExternalInterface.call("inHTML");
this.txtInMsg.text = txtMsg;
}
else
{
mx.controls.Alert.show("외부 인터페이스를 갖춘 컨테이너에 포함되어있지 않습니다.");
}
}
]]>
</mx:Script>
<mx:HBox width="100%" height="25">
<mx:TextInput id="txtFxMsg"/>
<mx:Button label="Flex Alter" click="showPopup()"/>
</mx:HBox>
<mx:HBox width="100%" height="25">
<mx:TextInput id="txtJsMsg"/>
<mx:Button label="JavaScript Alter" click="jsAlter()"/>
</mx:HBox>
<mx:HBox width="100%" height="25">
<mx:TextInput id="txtInMsg"/>
<mx:Button label="HTML에서 텍스트 읽어오기" click="innerHTML()"/>
</mx:HBox>
</mx:Application>
JavaScript 코드 (common.js)
{
alert(msg);
}
function inHTML()
{
var msg = document.getElementById("txtBox").value;
return msg;
}
function callApp()
{
document.getElementById("Demo").flexFunc();
}
HTML 코드 (ExternalInterface.html)
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<script src="common.js" language="javascript"></script>
<style>
body { margin: 0px; overflow:hidden }
</style>
</head>
<body scroll="no">
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
id="Demo" width="100%" height="80%"
codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
<param name="movie" value="Demo.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="#869ca7" />
<param name="allowScriptAccess" value="sameDomain" />
<embed src="Demo.swf" quality="high" bgcolor="#869ca7"
width="100%" height="100%" name="Demo" align="middle"
play="true"
loop="false"
quality="high"
allowScriptAccess="sameDomain"
type="application/x-shockwave-flash"
pluginspage="http://www.adobe.com/go/getflashplayer">
</embed>
</object>
<br>
<input type="text" id="txtBox">
<input type="button" onclick="callApp()" value="Flex로 텍스트 보내기">
</body>
</html>
먼저 mxml파일을 보자!
initialize="initApp()">
<mx:Application> 태그를 보면 initialize="initApp()" 를 찾을 수 있다. initialize이벤트가 발생했을 때 즉, 컴포넌트가 초기 설정값 처리를 마쳤을 때 initApp()를 호출하게 된다. Flex Builder 2에서 메소드명이나 변수명을 Ctrl를 누른상태에서 클릭하면 그 정의로 이동하게 된다. initApp()를 Ctrl + 클릭을 해보자!!
{
// 외부 인터페이스를 갖춘 컨테이너에 포함되어있는지 여부를 나타낸다.
isAvailable = ExternalInterface.available;
if (isAvailable)
{
// 컨테이너로부터 호출할 수 있도록 등록한다.
// 호출에 성공하면, JavaScript로부터 호출할 수 있다.
ExternalInterface.addCallback("flexFunc", innerHTML);
}
}
isAvailable변수는 <mx:Script>시작부분에서 private var isAvailable:Boolean = false; 이와같이 전역변수로 선언하였기 때문에 별도의 정의없이 바로 사용한다.
isAvailable = ExternalInterface.available;
ExternalInterface.abailable는 외부 인터페이스를 갖춘 컨테이너에 Flash Player가 포함되어있는지 여부를 나타내며 true, false로 값을 리턴한다.
Flash Player가 독립적으로 실행이 되었다면 false가 리턴되며, HTML과 같이 Flash Player가 포함될 수 있는 컨테이너에 포함되서 실행이 되었다면 true가 리턴된다.
ExternalInterface.addCallback("flexFunc", innerHTML);
true일 경우 위 구문을 수행하는데 addCallback는 외부 API에서 호출할 수 있도록 등록해 두는 것이다. innerHTML()이라는 함수를 flexFunc라는 이름으로 호출할 수 있다.
이제 로딩이 완료되었다. mxml파일을 컴파일한 swf 파일과 js, html파일을 같은 디렉토리에 모아놓고 html파일을 실행하면 다음과 같은 화면을 볼 수 있다.
버튼을 하나씩 설명하겠다.
Flex Alter버튼을 클릭하면 옆의 텍스트박스에 입력한 내용을 Flex에서 제공하는 Alter창으로 출력한다.
JavaScript Alter버튼을 클릭하면 왼쪽의 텍스트박스에 입력한 내용을 자바스크립트의 Alter창으로 출력한다.
HTML에서 텍스트 읽어오기버튼을 클릭하면 하단의 Flex로 텍스트 보내기 버튼 왼쪽에 있는 텍스트박스에 입력되어있는 값을 읽어들여서 HTML에서 텍스트 읽어오기 버튼 오늘쪽의 텍스트박스에 입력한다.
마지막으로 Flex로 텍스트 보내기 버튼은 HTML의 <input type="button">버튼으로 왼쪽의 텍스트박스에 있는 값을 Flex의 3번째 텍스트박스에 입력하는 기능을 한다.
다시 mxml 파일을 보자
<mx:TextInput id="txtFxMsg"/>
<mx:Button label="Flex Alter" click="showPopup()"/>
</mx:HBox>
HBox는 내부의 컨트롤을 가로로 정렬하는 Layout 컴포넌트이다.
따라서, 위 코드처럼 작성하면 TextInput 컨트롤 컴포넌트옆에 Button 컨트롤 컴포넌트가 나열된다. 버튼을 클릭하면 click 이벤트가 발생되고 showPopup()를 호출한다.
{
mx.controls.Alert.show(txtFxMsg.text);
}
showPopup()는 txtFxMsg에 입력된 값을 mx.controls.Alter.show로 화면에 출력한다. 즉, Flex의 Alter창으로 txtFxMsg의 값을 출력한다.
두번째 HBox를 보자!
<mx:TextInput id="txtJsMsg"/>
<mx:Button label="JavaScript Alter" click="jsAlter()"/>
</mx:HBox>
{
// 외부 인터페이스를 사용할 수 있다면..
if (isAvailable)
{
// 외부 인터페이스(HTML)의 자바스크립트를 호출한다.
ExternalInterface.call("jsAlter", txtJsMsg.text);
}
else
{
mx.controls.Alert.show(txtJsMsg.text);
}
}
isAvailable="true"이면 자바스크립트를 호출하고 false면 액션스크립트를 실행한다.
ExternalInterface.call("jsAlter", txtJsMsg.text);
HTML에서 호출할 수 있는 자바스크립트 함수 jsAlter()를 호출하고 파라미터로 txtJsMsg.text를 갖는다.
이 call() 메소드는 Flash Player 컨테이너로 공개되고 있는 함수를 호출하거나, HTML의 자바스크립트 함수를 호출한다. 지정된 함수가 없거나 사용할 수 없을 경우 null이 리턴되며, 그 이외에는 함수의 리턴값을 반환한다.
이제 마지막 HBox를 보자!
<mx:TextInput id="txtInMsg"/>
<mx:Button label="HTML에서 텍스트 읽어오기" click="innerHTML()"/>
</mx:HBox>
{
if (isAvailable)
{
var txtMsg:String = ExternalInterface.call("inHTML");
this.txtInMsg.text = txtMsg;
}
else
{
mx.controls.Alert.show("외부 인터페이스를 갖춘 컨테이너에 포함되어있지 않습니다.");
}
}
isAvailable가 true이면 inHTML() 자바스크립트 함수를 호출하고 그 반환값을 txtMsg변수로 받고 그 값을 txtInMag에 할당한다. false면 외부 인터페이스를 갖춘 컨테이너에 포함되지 않았음을 알려준다.
이제 자바스크립트와 HTML 파일을 보자
<input type="button" onclick="callApp()" value="Flex로 텍스트 보내기">
{
document.getElementById("Demo").flexFunc();
}
HTML에서 Flex를 Demo라는 id로 등록했다. 따라서, Flex 오브젝트롤 호출할 때 위와같이 호출한다. 위 소스는 Flex의 flexFunc()함수를 호출하는 것이다. 앞에서 ExternalInterface.addCallback("flexFunc", innerHTML); 이 구문을 기억할 것이다. 자바스크립트로 flexFunc()를 호출하면 Flex에서 받아서 innerHTML()를 실행하게 된다.
이제 ExternalInterface.html을 실행하자!
그리고 각각의 TextInput 컨트롤에 값을 입력하고 버튼을 클릭해 보자
또한, HTML의 input태그에도 값을 넣고 버튼을 클릭해서 Flex와 통신이 잘 이루어지는지 확인해보자.