AngularJS:即使objectEquality = true,也不会触发作用域监视>

问题描述 投票:1回答:2
在我的控制器中,我有:

$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 named”,但未调用resultSet上的实际监视。我已经验证了对对象resultSet的确是由于对size()的调用而发生了突变,并且由于我已经将watch参数设置为objectEquality来设置了true,所以我的理解是应该将更改更改为拿起并触发watch。为什么没有发生这种情况,我该如何实现呢?

更新

我进行了以下更改以使其起作用:

创建了一个简单的计数器变量,每次在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

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

    JSbin using private vars (revealing module pattern) showing the problem
  1. JSbin using normal objects works
  • 在我的控制器中,我有:$ scope。$ watch('numRuns',function(newVal,oldVal){如果(newVal === oldVal)return; updateNumResults();});函数updateNumResults(){$ scope.resultSet.size($ scope ....
  • javascript html angularjs angularjs-scope
    2个回答
    2
    投票
    此答案基于问题中的一些讨论:

    0
    投票
    我的猜测是,您已将指令配置为具有单独的隔离范围(已将哈希值传递给scope参数)。由于您已经在指令的范围内配置了监视,因此您需要确保此范围与控制器范围相同或继承它。
    © www.soinside.com 2019 - 2024. All rights reserved.