我发现当$ watch的目标设置为与当前持有的值相同时,$ scope。$ watch不会被触发。
我创建了一个示例JSFiddle(http://jsfiddle.net/VKHVq/)来显示行为。
在第一个输入字段中输入任意值( position_total )。 total_before_discount 会按原样进行调整,还会调整 total_before_discount $ watch触发器。由于折扣百分比为0%,total_discount将始终保持为0.尽管0会一直分配到$ scope.total_discount,但不幸的是,'total_discount'上的监视不会被触发。我做错了什么或是出于这种行为?
对我来说,这种行为看起来并不像预期的那样,因为我们在$ watch函数中得到newValue和oldValue,并且可以在很多angular.js $ watch示例中看到,建议测试if(newValue === oldValue){return}。
HTML
<div id="container" ng-controller="MyCtrl">
<div>Position total: <input type="number" ng-model="position_total"/>
<div>Total before discount: {{total_before_discount}}</div>
<div>Discount (in %): <input type="number" ng-model="discount"/>
<div>Total discount: {{total_discount}}</div>
<div>Total after discount: {{total_after_discount}}</div>
</div>
JS
var myApp = angular.module('myApp', ['ngAnimate']);
function MyCtrl($scope) {
$scope.position_total = 0;
$scope.total_before_discount = 0;
$scope.discount = 0;
$scope.total_discount = 0;
$scope.total_after_discount = 0;
calculatePositionTotal = function() {
// Dummy method to simulate position calculation
$scope.total_before_discount = $scope.position_total
};
calculateTotalDiscount = function() {
var total_discount = ($scope.total_before_discount / 100) * $scope.discount;
console.log('Going to set total_discount to ' + total_discount);
$scope.total_discount = total_discount;
};
calculateTotalAfterDiscount = function() {
$scope.total_after_discount = $scope.total_before_discount - $scope.total_discount;
};
$scope.$watch('position_total', function (newValue, oldValue) {
calculatePositionTotal();
});
$scope.$watch('total_before_discount', function (newValue, oldValue) {
calculateTotalDiscount();
});
$scope.$watch('discount', function (newValue, oldValue) {
calculateTotalDiscount();
});
$scope.$watch('total_discount', function (newValue, oldValue) {
console.log('total_discount $watch triggered...');
calculateTotalAfterDiscount();
});
}
答案 0 :(得分:4)
答案 1 :(得分:2)
total_discount的初始值为0,当您第一次设置监视时,它会被oldValue和newValue触发为0
。之后,在total_discount的值发生变化之前,手表不会触发。如果您继续为其指定值0,则手表不会触发。
只有在价值发生变化时才会触发监视,除非文档中提到的极少数情况
在观察者注册范围后,监听器fn是 异步调用(通过$ evalAsync)来初始化观察者。在 在极少数情况下,这是不可取的,因为在何时调用侦听器 watchExpression的结果没有改变。检测这种情况 在监听器fn中,您可以比较newVal和oldVal。如果 这两个值是相同的(===)然后监听器被调用 初始化。