为什么即使将 objectEquality 设置为 true,$watch 也不会触发?
Why is $watch not firing even with objectEquality set to true?
在下面的代码中,$watch
应该在变量 scores
改变时执行函数 recalculateInfoBox
。然而,它什么也没做。
我已经阅读了添加 true
作为 $watch 的第三个变量通常可以解决问题,但在这种情况下 $watch 仍然不会触发。
我还需要更改什么才能触发 $watch?
<html ng-app="mainModule">
<head>
<style type="text/css">
</style>
</head>
<body ng-controller="mainController" >
<div>Scores: <input type="text" ng-model="scores" ng-list style="width:500px" placeholder="Enter comma-separated list..."/></div>
<div>You have {{scores.length}} items.</div>
<hr/>
ng-style:
<div ng-style="{'width': infoBox.width, 'background-color': infoBox.backgroundColor}">
This is the info.
</div>
<button ng-click="infoBox.width = '300px'">small</button>
<button ng-click="infoBox.width = '800px'">large</button>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script>
var mainModule = angular.module('mainModule', []);
function mainController($scope) {
$scope.scores = [];
$scope.infoBox = {width: '300px', backgroundColor: '#ddd'};
var recalculateInfoBox = function () {
console.log('in recalc');
$scope.infoBox.width = '100px';
};
$scope.$watch('scores', 'recalculateInfoBox', true);
}
</script>
</body>
</html>
$scope.$watch
接受一个回调函数(不是函数名)。
所以,改成这个应该可行:
var recalculateInfoBox = function () {
console.log('in recalc');
$scope.infoBox.width = '100px';
};
$scope.$watch('scores', recalculateInfoBox, true);
来自the docs:
$watch(watchExpression, listener, [objectEquality]);
Registers a listener callback to be executed whenever the
watchExpression changes.
问题不是因为对象相等,而是因为 listener 必须是函数引用而不是函数名称。与作为第一个参数(通常作为字符串提供)的作用域 属性 求值不同,angular 甚至不从作用域求值函数(即使您将方法添加为 属性 范围对象)。
$scope.$watch('scores', 'recalculateInfoBox', true);
应该是
$scope.$watch('scores', recalculateInfoBox, true);
angular.module('app', []).controller('ctrl', function($scope) {
$scope.scores = [];
$scope.infoBox = {
width: '300px',
backgroundColor: '#ddd'
};
var recalculateInfoBox = function() {
console.log(arguments);
$scope.infoBox.width = '100px';
};
$scope.$watch('scores', recalculateInfoBox);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div>Scores:
<input type="text" ng-paste="handlePaste($event)" ng-model="scores" ng-list style="width:500px" placeholder="Enter comma-separated list..." />
</div>
<div>You have {{scores.length}} items.</div>
<hr/>ng-style:
<div ng-style="{'width': infoBox.width, 'background-color': infoBox.backgroundColor}">
This is the info.
</div>
<button ng-click="infoBox.width = '300px'">small</button>
<button ng-click="infoBox.width = '800px'">large</button>
</div>
而且在处理 ng-list 时,您甚至可能不需要对象相等性,即 $scope.$watch('scores', recalculateInfoBox);
应该也能正常工作。
在下面的代码中,$watch
应该在变量 scores
改变时执行函数 recalculateInfoBox
。然而,它什么也没做。
我已经阅读了添加 true
作为 $watch 的第三个变量通常可以解决问题,但在这种情况下 $watch 仍然不会触发。
我还需要更改什么才能触发 $watch?
<html ng-app="mainModule">
<head>
<style type="text/css">
</style>
</head>
<body ng-controller="mainController" >
<div>Scores: <input type="text" ng-model="scores" ng-list style="width:500px" placeholder="Enter comma-separated list..."/></div>
<div>You have {{scores.length}} items.</div>
<hr/>
ng-style:
<div ng-style="{'width': infoBox.width, 'background-color': infoBox.backgroundColor}">
This is the info.
</div>
<button ng-click="infoBox.width = '300px'">small</button>
<button ng-click="infoBox.width = '800px'">large</button>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script>
var mainModule = angular.module('mainModule', []);
function mainController($scope) {
$scope.scores = [];
$scope.infoBox = {width: '300px', backgroundColor: '#ddd'};
var recalculateInfoBox = function () {
console.log('in recalc');
$scope.infoBox.width = '100px';
};
$scope.$watch('scores', 'recalculateInfoBox', true);
}
</script>
</body>
</html>
$scope.$watch
接受一个回调函数(不是函数名)。
所以,改成这个应该可行:
var recalculateInfoBox = function () {
console.log('in recalc');
$scope.infoBox.width = '100px';
};
$scope.$watch('scores', recalculateInfoBox, true);
来自the docs:
$watch(watchExpression, listener, [objectEquality]);
Registers a listener callback to be executed whenever the watchExpression changes.
问题不是因为对象相等,而是因为 listener 必须是函数引用而不是函数名称。与作为第一个参数(通常作为字符串提供)的作用域 属性 求值不同,angular 甚至不从作用域求值函数(即使您将方法添加为 属性 范围对象)。
$scope.$watch('scores', 'recalculateInfoBox', true);
应该是
$scope.$watch('scores', recalculateInfoBox, true);
angular.module('app', []).controller('ctrl', function($scope) {
$scope.scores = [];
$scope.infoBox = {
width: '300px',
backgroundColor: '#ddd'
};
var recalculateInfoBox = function() {
console.log(arguments);
$scope.infoBox.width = '100px';
};
$scope.$watch('scores', recalculateInfoBox);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div>Scores:
<input type="text" ng-paste="handlePaste($event)" ng-model="scores" ng-list style="width:500px" placeholder="Enter comma-separated list..." />
</div>
<div>You have {{scores.length}} items.</div>
<hr/>ng-style:
<div ng-style="{'width': infoBox.width, 'background-color': infoBox.backgroundColor}">
This is the info.
</div>
<button ng-click="infoBox.width = '300px'">small</button>
<button ng-click="infoBox.width = '800px'">large</button>
</div>
而且在处理 ng-list 时,您甚至可能不需要对象相等性,即 $scope.$watch('scores', recalculateInfoBox);
应该也能正常工作。