AngularJS多个$ watch会在控制器初始化时导致多个请求

时间:2013-05-18 08:38:01

标签: angularjs watch

考虑以下代码;

function ListCtrl($scope){

  this.fetchResults = function(){};

  // so I can pass this as a reference & spyOn fetchResults
  function fetchResults = function(){return this.fetchResults()}.bind(this);

  $scope.page = 1;
  $scope.order = null;

  $scope.$watch('page',fetchResults);
  $scope.$watch('order',fetchResults);

  this.fetchResults();

}

我想以这种方式编写此代码,因此我可以测试每个监视是否触发fetchResults。但是这样,ListCtrl被初始化时,它会调用fetchResults 3次

  1. 明确调用
  2. for $watch('page')
  3. for $watch('order')
  4. 如何在初始化时仅ListCtrl调用fetchResults一次?

2 个答案:

答案 0 :(得分:4)

来自$scope.$watch docs

  

在观察者注册观察者之后,异步调用侦听器fn(通过$ evalAsync)来初始化观察者。在极少数情况下,这是不合需要的,因为当watchExpression的结果没有改变时会调用监听器。要在侦听器fn中检测此场景,您可以比较newVal和oldVal。如果这两个值相同(===)则由于初始化而调用了监听器。

所以你可以这样做:

function watchFetchResults(newValue, oldValue) {
  if(newValue !== oldValue){
    fetchResults();
  }
}

$scope.$watch('page',watchFetchResults);
$scope.$watch('order',watchFetchResults);

答案 1 :(得分:1)

你也可以这样做:

$scope.$watch('page + order', fetch);

这将同时观察两个表达式,只需将它们以角度表达式连接起来。