天天看點

優化Angularjs的$watch方法

Angularjs的$watch相信大家都知道,而且也經常使用,甚至,你還在為它的某些行為感到惱火。比如,一進入頁面,它就會調用一次,我明明希望它在我初始化之後,值再次變動才調用。這種行為給我們帶來許多麻煩。而我們今天就是要優化$watch的寫法,來解決這些問題。

一.推薦寫法:

$scope.$watch('xxx',function(newVal,oldVal){
if(newVal === oldVal || oldVal==undefined){
  //不執行代碼
}else{
  //執行你的代碼
}})           

為什麼這麼寫?聽我慢慢道來。

1.newVal===oldVal

首先,我們做一個測試。

$scope.$watch('name',function(newVal,oldVal){
    console.log('oldVal',oldVal)        //undefined
    console.log('newVal',newVal)        //undefined
    if(newVal === oldVal || oldVal==undefined){
    //不執行代碼
    }else{
  //執行你的代碼
    }
})           

我們監聽name的改變,一開始進來,沒有初始化時,都為undefined。

然後,我們先定義name

$scope.name="張三";
$scope.$watch('name',function(newVal,oldVal){
    console.log('oldVal',oldVal)        //張三
    console.log('newVal',newVal)        //張三
    if(newVal === oldVal || oldVal==undefined){
    //不執行代碼
    }else{
  //執行你的代碼
}})           

可以看到,一開始進來就都是張三。

由此可知,當監聽器函數初始化時,newVal和oldVal總是相等的,是以,此時我們可以判斷兩個值是否相等,來執行我們想要的操作。

2.oldVal==undefined

為什麼要判斷oldVal==undefined?因為,當我們給name指派的時候,會有一個undefinde變為有值的過程。是以當你不想在第一次指派時,就執行方法,這麼幹就對了。

我們給name的指派套一個timeout,模仿異步調用,在實際項目中,我們的name通常都是從接口擷取的。

$timeout(function(){
$scope.name="張三";
},500)           

然後,你再觀察一下watch

$scope.$watch('name',function(newVal,oldVal){
    console.log('oldVal',oldVal)        //undefined
    console.log('newVal',newVal)        //張三
    if(newVal === oldVal || oldVal==undefined){
    //不執行代碼
    }else{
  //執行你的代碼
}})           

以上就是watch需要注意的一些事項。然後,我們接下來讨論的是如何監聽數組的變化,這就要用到另一個監聽方法,$watchCollection。

二.watchCollection

大家,可以運作以下代碼,

https://codepen.io/hanwolfxue/pen/XYyVYv?editors=1010

出來的樣子長這樣

優化Angularjs的$watch方法

好好觀察一下watch和watchCollection的行為,可以發現watch是監聽不到數組的變化的,是以,如果你要監聽的是一個數組的話,請用watchCollection代替watch.

以上兩點就是今天要說的優化,當然$watch還有很多其他内容,感興趣的小夥伴可以繼續研究一下。

繼續閱讀