2012-06-06 3 views
5

어리석은 것처럼 보일지 모르지만, 배열 내용이으로 변경되면 요즘 JS가 이벤트를 발생시킬 것으로 기대할 수 있습니다.배열 항목 값이 변경되면 콜백을받을 수 있습니까?

변수이 변경되면 알림을받는 것과 관련하여 몇 가지 질문을 받았습니다 (getter 또는 setter 정의). 그리고 a way to do that있을 것 같습니다 (IE6 +를 포함한 대부분의 브라우저 적어도)

내 문제는 내가 배열 변경 내부 항목 경우 알림을받을려고한다는 것입니다 : 분명히

var ar = ["one", "two", "three"]; 
    // setting the whole array will call the custom setter method 
    // (assuming you defined it) 

    ar = ["one", "three", "five"]; 

    // however, this will only call the getter method and won't call the setter 
    // without defining custom setters for every item in the array. 

    ar[1] = "two"; 

, 난 코더가 구식 자바 스타일 인 .getVale() 및 .setValue() 함수를 사용하여 데이터에 액세스/수정하는 것을 방지해야합니다.

+0

Backbone.js는 컬렉션 모델이 변경 될 때 이벤트를 트리거 할 수 있습니다. 꽤 똑같은 것은 아니지만 어떻게하는지 볼 수 있습니다. – asawyer

+1

당신은 개체의 개인 변수로 배열을 가질 수 있습니다, 그때 변수를 변경하는 유일한 방법은 이벤트를 발생시킬 수있는 그 객체에 대한 방법을 사용하는 것입니다 ... –

+1

[observable pattern] (http://jsclass.jcoglan.com/observable.html) – MilkyWayJoe

답변

0

을보고 느려질, 실제로 해결책이있다. 읽기가 발생 후 원래의 값으로 짧은 시간을 비교하는 getter 메소드에의 setTimeout 장소 :

addProperty(myObject, 'vals', 
    function() { 
     var _oldVal = "" + this._val; 
     var _parent = this; 
     console.log('getter!'); 
     setTimeout(function() { 
      var curVal = "" + _parent._val; 
      if (curVal != _oldVal) 
       console.log('array changed!'); 
     }, 200); 
     return this._val; 
    }, 
    function (value) { 
     console.log('setter!'); 
     this._val = value; 
    }); 

    myObject.vals = ["one", "two", "three"]; 
    myObject.vals[1] = "five"; 
3

요컨대, 아닙니다. Arrays은 이벤트 디스패치 메커니즘을 제공하지 않으며 API에는 콜백 유형 기능이 포함되어 있지 않습니다. 에서

이상 : 다른 사람이 언급 한 것처럼, ... 배열을 포장 할 수 있습니다 그리고 그것은 배열의 내용을 폴링 할 수도 있습니다

function watchArray(arr, callback) { 
    var oldVal = "" + arr; 
    setInterval(function() { 
     var curVal = "" + arr; 
     if (curVal != oldVal) { 
      callback(); 
      oldVal = curVal; 
     } 
    }, 100); 
} 

을하지만이 방법은 몇 가지 명백한 문제가있다 : 폴링, 그것은 '

를 사용하여 노트 John Dyer에서 addProperty 방법을 구현하기 : LL @ 데이비드 Wolever의 코드와 다른 의견에 따라 배열의 무리 등을 확인

+0

이 게시물 주셔서 감사합니다. 배열 요소가 변경되면 getter가 호출되기 때문에 => getter + delay + comapre = change 알림을 비교할 수 있습니다. 느린 문제는 어떤 요소가 변경되었는지 찾는 것입니다 (저에게 문제가되지 않음). – MandoMando

+1

위의 @Phrogz에서 제안한 새로운 defineProperty 메서드는 어떻습니까? –

0

나는 timeout 기반 솔루션은 최상의하지 생각합니다. 당신은 단지 배열을 수정하는 푸시를 사용하여 팝업 경우
, 당신은 (모니터링 할 또는 일부 객체) pushpopArray 프로토 타입의 메소드를 오버라이드 (override) 할 수 있습니다

var myWatchableArr = []; 
myWatchableArr.setChangeCallback = function(callback){ 
    this.changeCallback = callback; 
} 
myWatchableArr.push = function(e){ 
    Array.prototype.push.call(this,e); 
    if(typeof this.changeCallback == "function") 
     this.changeCallback(this); 
} 
myWatchableArr.push(3); 
myWatchableArr.setChangeCallback(function(arr){ 
    console.log("the array has been changed", arr); 
}); 
// now watching for changes 
myWatchableArr.push(4); 

푸시와 팝이없는 경우 충분하면 myWatchableArr[3]=value 대신 myWatchableArr.setAt(3, value)과 같이 사용할 setAt 메서드를 추가 할 수 있습니다.

관련 문제