In my controller I have:
$scope.$watch('numRuns', function(newVal, oldVal) {
if (newVal === oldVal) return;
updateNumResults();
});
function updateNumResults() {
$scope.resultSet.size($scope.numRuns);
console.log("updateNumResults called");
}
The size method in ResultSet looks like:
function size(n) {
if (n === undefined) return numResults_; // no arg => using as getter
numResults_ = n;
return this;
}
In my view I have:
Number of runs: <input ng-model="numRuns"/>
In my directive I have:
scope.$watch('resultSet', function(newVal, oldVal) {
console.log("change in result set");
createFromScratch();
}, true); // use object equality
If I type into the input box in the browser, I'll see the output "updateNumResults called", but the actual watch on resultSet
is not called. I have verified that the object resultSet
is indeed getting mutated by the call to size()
, and since I have setup the watch
with the objectEquality
parameter set to true
, my understanding was that the change should be getting picked up and triggering the watch
. Why is that not happening and how can I make it happen?
I made the following changes to make it work:
Created a simple counter variable that I manually change each time I call any mutator method on resultSet:
function updateNumResults() {
$scope.resultSet.size($scope.numRuns);
$scope.resultSetChanged++;
console.log("updateNumResults called");
}
and I watch that instead in the directive:
function watchResultSet() {
scope.$watch('resultSetChanged', function(newVal, oldVal) {
console.log("change in result set");
createFromScratch();
});
}
This solution works fine, and is probably less resource intensive, but I would still like to know why the original solution is not working.
Sh0ber's idea was correct. The problem was with private vars.
This answer is based on some discussion in the question:
This code will work if the resultSet
object is mutated. After looking at the size
method it appeared to only be altering some private vars in resultSet
's constructor. The resultSet
object itself was not changing and so the $watch
was never triggered.