scaleform.minarto.com

Object.watch 를 이용한 데이터 바인딩 3 본문

Communication

Object.watch 를 이용한 데이터 바인딩 3

미나토 2012. 4. 12. 10:41

http://scaleform.minarto.com/343 에서 이어집니다


앞선 코드가 일단 돌아가긴 합니다만... 좀더 테스트 해보면 한가지의 키값에만 반응(?)을 합니다.


키값별로 실행함수들을 묶어놓을 필요가 있는 셈이죠...


그래서 __binds__ 속성을 그냥 오브젝트로 선언해 각 키값으로 __binds__ 의 키를 만들어 배열을 값으로 넣어서 사용해야합니다


bind 함수에서는 

$t.__binds__ = {};

이렇게 되어야 하고


__bindHandler__ 함수는 네번째 인자로 해당 키값으로 검색된 배열을 인자로 던져줍니다

__bindHandler__($p, $old, $new, $binds:Array):Void

이렇게 되는 것이죠...


addBind 는 다음과 같이 구현합니다.


function addBind($key, $handler, $handlerScope) {

var binds:Array = this["__binds__"][$key];    //    해당 키값으로 실행함수 배열을 검색

if (!binds) {    // 없으면 생성해서 추가

binds = [];

this["__binds__"][$key] = binds;

}

for (var i = 0, c = binds.length; i < c; i += 2) {

if (binds[i] === $handlerScope && binds[i + 1] == $handler) {

return this;

}

}

binds.push($handler, $handlerScope);

this.watch($key, this["__bindHandler__"], binds);    //    실행 핸들러 함수에 마지막 인자로 검색된 배열값을 던진다

return this;

}


이렇게 되는 겁니다. 이제부터는 여러 키값에 대응할 수 있게 되었습니다.


그럼 이걸 더 정리한 최종 코드를 볼까요...



class com.minarto.data.Binding {

public static function bind($t) {

if ($t.__binds__) return $t;

$t.__binds__ = {};

$t.__bindHandler__ = Binding.prototype.bindHandler;

$t.addBind = Binding.prototype.addBind;

return $t;

}

private function bindHandler($p, $old, $new, $binds){

for (var i = 0, c = $binds.length; i < c; i += 2) {

$binds[i].call($binds[i + 1], $new, $old);

}

return $new;

}

private function addBind($key, $handler, $handlerScope) {

var binds:Array = this["__binds__"][$key];

if (!binds) {

binds = [];

this["__binds__"][$key] = binds;

}

for (var i = 0, c = binds.length; i < c; i += 2) {

if (binds[i] === $handlerScope && binds[i + 1] == $handler) {

return this;

}

}

binds.push($handler, $handlerScope);

this.watch($key, this["__bindHandler__"], binds);

return this;

}

}


이정도로 as2용 Binding.as 클래스를 만들어놓으면 어디에서건 간편한 바인딩을 사용할 수 있습니다.


장점을 정리해볼까요??


1. 클라이언트가 해당 UI의 초기화를 기다리지 않아도 됩니다. 예를 들어 _root 에 player 만 존재하면 됩니다.

2. 클라이언트의 값이 변경되었을 때, 클라이언트가 각 UI에 접근해서 해당한 인보크 함수를 실행하지 않아도 됩니다. _root 에 있는 값 하나만 변경하면 바인딩된 모든 UI에 적용됩니다.

3. 각 UI별로 인보크 함수를 실행하는 것이 아니므로 클라이언트와 UI 개발자가 UI마다 인보크 함수를 미리 약속할 필요가 없습니다.



자 이번에는 숙제...


1. 단점도 있겠죠? 한번 찾아보세요

2. delBinding($key, $handler, $handlerScope) 을 구현해보세요

3. 실행함수에 인자를 던질 수 있도록 바꿔보세요