1

在我的控制器中,我有:

$scope.$watch('numRuns', function(newVal, oldVal) {
  if (newVal === oldVal) return;
  updateNumResults();
});

function updateNumResults() {
  $scope.resultSet.size($scope.numRuns);
  console.log("updateNumResults called");
}

ResultSet 中的 size 方法如下所示:

  function size(n) {
    if (n === undefined) return numResults_; // no arg => using as getter
    numResults_ = n;
    return this;
  }

在我看来,我有:

Number of runs: <input ng-model="numRuns"/>

在我的指令中,我有:

scope.$watch('resultSet', function(newVal, oldVal) {
  console.log("change in result set");
  createFromScratch();
}, true); // use object equality

如果我在浏览器的输入框中输入,我会看到输出“updateNumResults called”,但实际上resultSet并没有调用手表。我已经验证了该对象resultSet确实因调用而发生了变异size(),并且由于我已将参数设置为 设置watch,因此我的理解是更改应该被拾取并触发. 为什么这没有发生,我怎样才能让它发生?objectEqualitytruewatch

更新

我进行了以下更改以使其正常工作:

创建了一个简单的计数器变量,每次我在 resultSet 上调用任何 mutator 方法时手动更改它:

  function updateNumResults() {
    $scope.resultSet.size($scope.numRuns);
    $scope.resultSetChanged++; 
    console.log("updateNumResults called");
  }

我在指令中看到了这一点:

  function watchResultSet() {
    scope.$watch('resultSetChanged', function(newVal, oldVal) {
      console.log("change in result set");
      createFromScratch();
    });
  }

该解决方案运行良好,并且可能占用资源较少,但我仍然想知道为什么原始解决方案不起作用。

使用 JSBIN 示例更新 2

Sh0ber 的想法是正确的。问题出在私有变量上。

  1. JSbin 使用私有变量(显示模块模式)显示问题
  2. 使用普通对象的 JSbin 有效
4

2 回答 2

2

该答案基于问题中的一些讨论:

如果对象发生突变,此代码起作用。resultSet在查看该size方法后,它似乎只是在更改resultSet构造函数中的一些私有变量。resultSet对象本身没有改变,因此从未$watch被触发。

于 2013-05-24T00:55:24.500 回答
0

我的猜测是您已将指令配置为具有单独的隔离范围(您已将哈希传递给范围参数)。由于您已经在指令的范围内配置了监视,因此您需要确保此范围与控制器范围相同,或者继承它。

阅读有关指令的 Angular 指南(尤其是关于范围配置)以获取更多信息。

于 2013-05-23T21:02:04.197 回答