logo
Tutorials Examples naver map js api v3 네이버 지도 API KVO 디자인

KVO 디자인

KVO(Key-Value Observing)는 객체의 속성에 접근할 때 해당 속성을 의미하는 문자열을 키(key)로 사용해 속성의 값(value)을 참조하는 매커니즘입니다. 또한 키에 대응하는 속성값의 변경 사항을 추적하는 역할을 합니다.

KVO 클래스 상속받기

KVO 클래스를 상속받으려면 클래스를 선언할 때 다음과 같이 해당 클래스의 prototype을 설정해야 합니다.

var MyClass = function() {
    // class initialization codes
};

MyClass.prototype = new naver.maps.KVO();
MyClass.prototype.constructor = MyClass;

MyClass.prototype.myMethod = function() {
    // implementation
};

위와 같이 MyClass를 선언하면 MyClass의 인스턴스는 KVO 클래스를 상속받은 객체가 됩니다.

var myKVO = new naver.maps.KVO();
var myClass = new MyClass();

myClass instanceof MyClass;         // true
myClass instanceof naver.maps.KVO;  // true

myKVO instanceof naver.maps.KVO;    // true
myKVO instanceof MyClass;           // false

Key-Value 이용하기

KVO 클래스를 상속받은 클래스는 setget 메서드를 이용해 키에 대응하는 값을 설정하거나 가져올 수 있습니다.

var MyClass = function() {
    this.set('zoom', 10);
};

MyClass.prototype = new naver.maps.KVO();
MyClass.prototype.constructor = MyClass;

MyClass.prototype.getZoom = function() {
    return this.get('zoom');
};

Key-Value 연결하기

KVO 클래스를 상속받은 클래스의 인스턴스는 bindTo 메서드를 이용해 키에 대응하는 값을 서로 동기화할 수 있습니다.

다음은 zoom 문자열을 키로 사용해 속성의 값을 설정하고, KVO 클래스를 상속받은 클래스의 두 인스턴스 간에 zoom 속성을 연결하는 예제입니다. myView 객체가 myModel 객체의 zoom 속성을 바인딩함으로써 해당 속성에 접근해 변경할 수 있습니다. 또한 zoom 속성의 상태 변경은 두 객체에 동일하게 적용됩니다.

var myModel = new naver.maps.KVO();
myModel.set('zoom', 11);

var myView = new naver.maps.KVO();

myView.bindKVO = function() {
    this.bindTo('zoom', myModel);
};

myView.bindKVO();

myView.get('zoom');         // 11

myModel.set('zoom', 21);
myModel.get('zoom');        // 21

myView.get('zoom');         // 21

속성을 바인딩할 때 속성의 이름을 별도로 지정해 동기화할 수 있습니다. 다음은 앞의 예제에서 zoom 속성을 myZoom이란 키로 지정해 연결하는 예제입니다.

myView.bindKVO = function() {
    this.bindTo('myZoom', myModel, 'zoom');
};

myView.bindKVO();

myView.get('zoom');           // undefined
myView.get('myZoom');         // 11

myModel.set('zoom', 21);

myView.get('myZoom');         // 21

bindTo 메서드의 세 번째 인수(targetKey)를 생략하면, 연결하려는 객체의 속성 목록에서 첫 번째 인수의 속성 이름을 찾아 연결합니다.

여러 개의 속성을 바인딩할 때는 배열 형태의 키를 지정해 이용할 수 있습니다. 다음은 myModel 객체의 zoom, center, centerPoint, scale 속성을 한 번에 연결하는 예제입니다.

var myModel = new naver.maps.KVO();
myModel.set('zoom', 11);
myModel.set('center', new naver.maps.LatLng(38, 127));
myModel.set('centerPoint', new naver.maps.Point(128, 128));
myModel.set('scale', 1);

var myView = new naver.maps.KVO();

myView.bindKVO = function() {
    this.bindTo([
            'zoom',
            'center',
            'centerPoint',
            'scale'
        ], myModel);
};

myView.bindKVO();

연결된 Key-Value 상태 변경 감지하기

KVO는 속성의 상태(내용) 변경을 {key}_changed 이름 규칙을 사용해 알립니다. 따라서 속성을 연결한 객체들은 해당 속성의 상태가 변경된 시점을 감지할 수 있습니다. 즉, 특정 속성의 상태가 변경되면 추가적으로 수행해야 할 것이 있을 때 유용하게 이용할 수 있습니다.

연결된 Key-Value 상태 변경 감지에 대한 자세한 설명은 KVO 상태 변경 알림를 참고합니다.

NAVER 지도 API v3은 속성의 상태 변경을 감지할 수 있도록 두 가지 방법을 제공합니다. 첫 번째는 {key}_changed 이름 규칙을 준수하는 메서드를 사용하는 것입니다. 다음은 myModel 객체의 zoom 속성을 변경하면 시스템 경고 창을 표시하는 예제입니다.

myView.zoom_changed = function(zoom) {
    alert('zoom 값이 '+ zoom +'으로 변경되었습니다!');
};

myModel.set('zoom', 14);

두 번째는 {key}_changed 이름 규칙을 준수하는 이벤트를 구독하는 것입니다. 다음은 위 예제를 이벤트 구독으로 처리하는 예제입니다.

var listener = naver.maps.Event.addListener(myView, 'zoom_changed', function(zoom) {
    alert('zoom 값이 '+ zoom +'으로 변경되었습니다!');
});

myModel.set('zoom', 14);

EventaddListener 메서드를 이용해 KVO 이벤트를 구독하면 removeListener 메서드를 이용해 구독을 취소할 수 있습니다.

var listener = naver.maps.Event.addListener(myView, 'zoom_changed', function(zoom) {
    alert('zoom 값이 '+ zoom +'으로 변경되었습니다!');
});

naver.maps.Event.removeListener(listener);

myModel.set('zoom', 14); // not notified