2014-10-10 30 views
1

我的代碼角`watch`不表現

function MyCtrl($scope, $log){ 

    $scope.name = 'guy'; 
    $scope.guy = {}; 


    function myWatch(){ 
    return function(newValue, oldValue){ 
     $log.info('these are the values',newValue, oldValue); 

     if (newValue === oldValue){ 
     $log.info('they are the same'); 
     } 
    } 
    } 

    $scope.$watch('guy',myWatch(), true); 

    $scope.guy = { 'hello' : 'world' }; 

} 

下面的代碼片段,您可以run on plunkr - 看控制檯打印!

的理念是:

  • 的值賦給scope屬性guy
  • 設置$watch對財產
  • 指定另一個值guy
  • 期待newValueoldValue是不同的,在控制檯日誌中看不到they are the same打印 - 失敗
    • 更具體我希望oldValue{}和NEWVALUE是{ 'hello':'world' }

我在做什麼錯了,我應該如何在需要時實現這個邏輯是什麼?

+4

你看到什麼是預期的行爲。在下一個摘要循環(由於控制器初始化)發生之前,您正在更改'guy'的值兩次。所以最初的手錶運行會顯示他們兩個相同。現在看看你的控制檯..在這個例子中http://plnkr.co/edit/pAND9x?p=preview。當我們將屬性值的變化推遲到下一個摘要週期時,您將得到您最初期望的結果。 – PSL 2014-10-10 13:24:57

回答

1

我相信您遇到計時問題,手錶沒有完全建立價值變動之前,當摘要最終運行值,如果你這樣做確實是相同的:

$timeout(function(){ 
    $scope.guy = { 'hello' : 'world' }; 
},3000,true); 

這將使您有足夠的時間進行手錶設置,並在稍後看到變化。有了這個改變,你的期望應該得到滿足。

編輯進一步解釋$手錶和消化週期:

$watch被稱爲在每個$digest cycle不管收視的改變與否,但是,listener僅稱爲第一$digest週期值,但直到觀察值發生變化才調用。此外,手錶可以在每個$digest循環中運行多次,因此listener可能會在第一個循環中多次調用。

Documentation

下面的代碼片段:

function MyCtrl($scope, $log, $timeout) { 
 

 
    $scope.name = 'guy'; 
 
    $scope.guy = {}; 
 

 

 
    function myWatch() { 
 
    return function(newValue, oldValue) { 
 
     $log.info('these are the values', newValue, oldValue); 
 

 
     if (newValue === oldValue) { 
 
     $log.info('they are the same'); 
 
     } else { 
 
     $log.info('they are different'); 
 
     } 
 
    } 
 
    } 
 

 
    $scope.$watch('guy', myWatch(), true); 
 

 
    $timeout(function() { 
 
    $scope.guy = { 
 
     'hello': 'world' 
 
    }; 
 
    }, 3000, true); 
 

 

 
}
<!DOCTYPE html> 
 
<html ng-app> 
 

 
<head> 
 
    <script data-require="[email protected]" data-semver="1.2.16" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script> 
 
    <link rel="stylesheet" href="style.css" /> 
 
    <script src="script.js"></script> 
 
</head> 
 

 
<body ng-controller="MyCtrl"> 
 
    <h1>Hello {{name}}!</h1> 
 
</body> 
 

 
</html>

+0

你能解釋爲什麼'watch'被解僱嗎?如果兩個值都相同? – 2014-10-10 13:49:45

+0

請參閱上面的編輯。 – 2014-10-10 14:06:05

3

由於手錶作爲摘要週期的一部分進行評估,因此沒有額外的更改。我創建了一個樣例,在一個函數中更改guy,該函數是通過點擊按鈕調用的。

我還調整了您的手錶功能只是功能,而不是返回功能的功能。

function myWatch(newValue, oldValue){ 
    $log.info('these are the values',newValue, oldValue); 

    if (newValue === oldValue){ 
    $log.info('they are the same'); 
    }  
} 

$ scope。$ watch('guy',myWatch,true);

http://plnkr.co/edit/qCyvyLyNDscdFcQ3rsUj?p=preview