일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 태그클라우드
- flash cs3
- flash player 10
- 스케일폼
- as3.0
- ApplicationDomain
- scaleform3
- MMOKit
- autodesk
- 샌프란시스코
- CLIK
- Chart
- 형변환
- DataBinding
- flash
- 플래시
- 수학정석
- as2
- watch
- 클릭
- KGC 2013
- scaleform4
- GDC
- addChild
- 집합의 연산
- Document Class
- 강좌
- 애드온
- as3
- scaleform
- Today
- Total
scaleform.minarto.com
Object.watch 를 이용한 데이터 바인딩 1 본문
http://scaleform.minarto.com/335
에 이어지는 글입니다
앞선 포스팅에서 watch 의 단점으로 하나의 속성에 하나의 핸들러만 연결할 수 있다고 했습니다.
레퍼런스에는
"단일 감시점만 속성에 등록될 수 있습니다. 같은 속성에 대해 이후에 Object.watch()를
호출하면 원래 감시점이 바뀝니다."
라고 쓰여있네요...
뭐, 그래봤자 해결 방법은 사실 너무 간단합니다.
var o = {level:1};
o.watch("level", hn);
function f0($n):Void{
trace("f0 : " + $n)
}
function f1($n):Void{
trace("f1 : " + $n)
}
function hn($p, $o, $n):Void{
f0($n);
f1($n);
}
o.level = 4;
이 정도 코드면 되는 것이죠...
해당 키값의 핸들러에 여러 함수를 실행시키도록 하면 되는 겁니다.
자, 이제 이걸 범용적으로 쓸 수 있도록 바꿔보겠습니다.
일단 함수 정의는 다음과 같습니다.
function addBinding($keyScope, $key:String, $handlerScope, $handler:String)
$keyScope 는 대상 객체입니다.
$key는 대상 객체의 감시할 키(속성)이죠...
$handlerScope, $handler 는 as2 용 EventDispatcher 를 사용해보셨으면 당연히 아시겠죠?
핸들러를 실행할 객체와 해당 핸들러명입니다.
addEevntListener 처럼 쓰는 것이죠...
var runData:Array = [];
배열을 하나 만들어야 합니다. 이 배열은 해당 키값의 핸들러에서 실행하게 될 함수들의 모음입니다.
그 배열에는 당연히 등록할 함수의 스코프와 함수명을 넣어야 합니다.
결국 이런 식이 되겠죠.
var runData:Array = [$handlerScope, $handler];
핸들러도 만들어야 하겠죠.
function($p:String, $oldValue, $newValue, $runData:Array){
var c:Number = $runData.length;
for (var i:Number = 0; i < c; i += 2) {
$runData[i][$runData[i + 1]]( $newValue );
}
return $newValue;
}
이정도면 되겠죠...
참고로 레퍼런스에도 나와있지만 핸들러의 반환값이 다시 해당 키의 값으로 들어가기 때문에 $newValue 를 반환해주도록 짜는 것이 좋습니다.
이제 watch 로 연결합니다.
$keyScope.watch($key, function, runData);
끝났습니다... 뭔가 아쉽죠?
function addBinding($keyScope, $key:String, $handlerScope, $handler:String) {
var runData:Array = $keyScope.__watchRunData__;
if (runData) {
var c:Number = runData.length;
for (var i:Number = 0; i < c; i += 2) {
if (runData[i] === $handlerScope && runData[i + 1] == $handler) {
return;
}
}
runData.push($handlerScope, $handler);
}
else {
runData = [$handlerScope, $handler];
$keyScope.__watchRunData__ = runData;
}
if (!$keyScope.__watchHandler__) {
$keyScope.__watchHandler__ = function($p, $oldValue , $newValue , $runData){
c = $runData.length;
for (i = 0; i < c; i += 2) {
$runData[i][$runData[i + 1]]( $newValue );
}
return $newValue;
}
}
$keyScope.watch($key, $keyScope.__watchHandler__, runData);
return $objectScope[$key];
}
자, 풀코드입니다~
물론 저는 더 개선해서 사용하고 있고.... 이놈은 블로그로 코딩(?)한거라 어딘가 오류가 있을지도...
다른 코드에서 참조하기 힘들도록 runData 와 function 의 이름에 __watchRunData__, __watchHandler__ 같은 이름을 썼습니다.
이렇듯 Object 에 마음껏 속성이든 function 이든 붙일 수 있는 것이 as2의 특성이죠...
var player = {};
player.level = 0;
addBinding(player, "level", this, "f");
addBinding(player, "level", this, "f2");
function f($n):Void{
trace(1 + ":" + $n);
}
function f2($n):Void{
trace(2 + ":" + $n);
}
player.level = 1;
이런 간단한 예를 돌려보면 f, f2 두 함수 모두 실행되는걸 확인할 수 있을 겁니다.
이번 포스팅에는 실제 코드를 좀 과하게 넣었더니, 포스팅이 좀 길어졌네요...
as2 / js 란 언어의 특징을 잘 모르시는 분은 조금 코드가 어려울 지도 모르겠습니다.
하지만 어려워도 뭔가 좀 아쉽습니다... 그건 다음 포스팅으로 넘어가죠...
http://scaleform.minarto.com/343 으로 이어집니다
p.s. 오늘은 4월 11일 총선.... 투표합시다~!!!