2013-10-09 131 views
1

如何偵聽在變量或對象屬性上設置的值,而不會丟失其他偵聽器。攔截javascript值設置器

例如

var myModel; 
myModel = 10; 
var myListener1 = function(oldVal, newVal) { 
    //do stuff 
} 
var myListener2 = function(oldVal, newVal) { 
    //do other stuff 
} 

在這裏我要myListener1和myListener2一旦某個值設置爲可變基於myModel被調用。後來在其他函數中,可能還需要將另一個偵聽器添加到setter上的myModel,以便它不應覆蓋現有的偵聽器。

我知道應該有一種方法用Object.defineProperty()來做到這一點。 另外,爲IE8 +提供跨瀏覽器的解決方案會很好。

+0

不知道有內置的東西,你必須寫一些代碼。查找「觀察者模式」或「pub/sub」作爲示例(如果我理解正確)。 – elclanrs

+1

你可以使用getters和setter,或者'Object.watch()' –

+0

@JoeSimmons你能舉個例子嗎? getters和setter是什麼意思? – danial

回答

3

對於下面的方法,你將不得不使用對象與屬性,但它的作品。


// this is very similar to using Object.watch() 
// instead we attach multiple listeners 
var myModel = (function() { 
    var actualValue, 
     interceptors = []; 

    function callInterceptors(newValue) { 
     for (var i = 0; i < interceptors.length; i += 1) { 
      interceptors[i](newValue); 
     } 
    } 

    return { 
     get value() { 
      // user never has access to the private variable "actualValue" 
      // we can control what they get back from saying "myModel.value" 
      return actualValue; 
     }, 

     set value(newValue) { 
      callInterceptors(newValue); 
      actualValue = newValue; 
     }, 

     listen : function (fn) { 
      if (typeof fn === 'function') { 
       interceptors.push(fn); 
      } 
     } 
    }; 
}()); 

// add a listener 
myModel.listen(function (passedValue) { 
    alert('You tried to set myValue to ' + passedValue); 
}); 

// add another listener 
myModel.listen(function (passedValue) { 
    alert('AAARRG! Why did you modify that value to ' + passedValue + '?!?!'); 
}); 

// our functions are called when we 
// modify our value 
myModel.value = 10; 

jsFiddle example

0

只能通過函數更改myModel的值,因此您可以在更改之前/之前運行偵聽器函數。

var myModel = 10, 
    myListener1 = function(oldVal, newVal) { 
     // do stuff 
    }, 
    myListener2 = function(oldVal, newVal) { 
    // do other stuff 
    }, 
    changeMyModel = function (value) { 
     myListener1(myModel, value); 
     myListener2(myModel, value); 
     myModel = value; 
     // do more stuff 
    }; 

    // changeMyModel(99) === myModel; true 

OR

var change = function (value) { 
     myListener1(myModel, value); 
     myListener2(myModel, value); 
     return value;   
    }; 
    // myModel = change(45); 
+0

我想能夠使用常規分配文字。像myModel = 10 – danial

+0

我不認爲這可能與JavaScript,另一種可能的方式是:'myModel = change(10)'其中'變化'運行偵聽器並返回10 –