2013-05-16 48 views
4

請參閱this jsfiddle;我有兩組通過ng-model連接的範圍變量的輸入框。

想想這個系統就像谷歌風格的搜索一樣,只需一個搜索框和一個「高級搜索」。

  • 當單個搜索輸入進行更新(在本例中,a)然後有更新有關「高級」輸入的函數。我在$scope.$watch('a', ...)中實現了這個。

  • 當「先進」搜索輸入進行編輯,然後單輸入也應該被更新(在$scope.$watch('b', ...)實施

當然,這兩個會產生一個反饋迴路 - a更新b當時的副相反,無限廣告 - 這是不好的!我希望能夠在上面的每個手錶的開始發出「暫停另一個觀察者」命令,然後(在更新另一個變量之後)發出「重新啓動看守人「命令,以防止這種情況。

有什麼辦法可以做這個?

+0

您的演示不會產生無限循環。它確實執行了幾次手錶,但這就是$消化循環在Angular中的工作原理。除非你的兩個$ watch語句每次都把'$ scope.a'的值改爲不同的東西,那麼你會沒事的。你的演示版本不是完全按照你想要的做的嗎? – Langdon

+0

你沒有一個無限循環。這是因爲$ watch不在$ apply內運行,所以$ digest不會發生,另一個$ watch不會被觸發。如果你在賦值之後放置一個範圍$ digest(),那麼你將會有一個無限循環。欲瞭解更多信息,請參閱http://docs.angularjs.org/guide/concepts#runtime –

+0

從你所說的我認爲這只是我的功能,從A到B不是從B的功能相反給正在建立競賽條件的A。由於AngularJS似乎能夠找出均衡情況,所以我應該沒問題。 - 我曾試着設置一個'lock'變量(如果你編輯A,變量在B被改變之前設置爲true,之後設置爲false;觀察者函數有一個if子句來防止反向變化,如果鎖定變量是真的;但我認爲Angular的異步特性阻止了它的工作) –

回答

1

我把一個簡單的例子放在一起。

<body ng-app="app" ng-controller="myTestCntrl"> 
    <input type="button" ng-click="increaseCounter()" value="Click me" /> clicked: {{counter}z} times<br/> 
    <input type="button" ng-click="pauseWatcher()" value="{{watcherBtnText}}" /> watched: {{internalCounter}} times<br/> 
    <strong>Number of $$watchers in $scope:</strong> {{$$watchers.length}} 
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script> 
    <script type="text/javascript"> 
     angular.module('app', []) 
      .controller('myTestCntrl', function myTestCntrl($scope) { 
      $scope.counter = 0; 
      $scope.pauseWatching = false; 
      $scope.watcherBtnText = 'Pause'; 
      $scope.internalCounter = -1; 
      $scope.increaseCounter = function() { 
       $scope.counter++; 
      }; 
      var listenerFn = function() { 
       if ($scope.pauseWatching) { 
        namedWatcher(); 
       } else { 
        $scope.internalCounter++; 
       }; 
      } 
      var namedWatcher = $scope.$watch('counter', listenerFn); 
      $scope.pauseWatcher = function() { 
       if ($scope.pauseWatching) { 
        $scope.watcherBtnText = 'Pause'; 
        $scope.pauseWatching = false; 
        $scope.internalCounter--; 
        namedWatcher = $scope.$watch('counter', listenerFn); 
       } else { 
        $scope.watcherBtnText = 'Continue'; 
        $scope.pauseWatching = true; 
        namedWatcher(); 
       }; 
      } 
     }); 
    </script> 
</body> 

演示上的jsfiddle:http://jsfiddle.net/BuriB/63sND/