2013-05-16 22 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/