为什么 ngModel 验证器代码似乎在 scope.$watch 更改之前 运行?
Why does the ngModel validator code seem to run before the scope.$watch changes?
我正在尝试使用自定义验证器创建一个 AngularJS 指令,以便我可以根据验证器显示错误消息。但是,我 运行ning 出错了,因为根据我输入的 console.log() 消息,验证器似乎在范围之前 运行ning。$watch() 。
指令如下:
angular
.module('app')
.directive('validateRefundAmount', validateRefundAmount);
validateRefundAmount.$inject = [ 'AmountConversionService', '$q' ];
function validateRefundAmount(AmountConversionService, $q) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, control) {
scope.$watch('orderDetails.refundAmount', function(newValue, oldValue) {
if (newValue === oldValue) {
console.log(newValue, oldValue);
return;
}
// Get Already Refunded Amount
var refundedAmount = scope.orderDetails.refundedAmount;
// Converts Amount To Pure Integers, Removing Decimal
var totalPaymentAmount = AmountConversionService.prepareAmountForCalculations(scope.orderDetails.paymentAmount, 10);
var totalRefundAmount = AmountConversionService.prepareAmountForCalculations(newValue || 0);
// Add Already Refunded Amount to Previously Refunded Amount to Get Total Refund
if (refundedAmount) {
totalRefundAmount += AmountConversionService.prepareAmountForCalculations(refundedAmount);
}
control.$validators.refundAmountTooHigh = function() {
if (totalRefundAmount > totalPaymentAmount) {
return false
}
return true;
}
});
}
};
}
应用的元素是一个没有值开头的文本输入框。当我在字段中键入“1”时,验证器不会 运行。当我在字段中添加一个“2”,生成“12”时,验证器 运行s 将“1”作为输入。当我将“3”添加到字段“123”时,也会发生同样的事情——它 运行s 为“12”,而不是新值“123”。
当我插入 console.log() 语句以查看发生了什么时,它看起来像验证程序代码 运行s 然后 scope.watch() 运行s 在验证器 运行 之后创建新值,但我不知道为什么或要搜索什么才能找到答案。
可能还有另一种方法可以做我想做的事情——我想做的是 运行 每次元素值改变时验证器。由于按键未检测到退格键,我无法在按键上使用绑定,也许可以在按键上使用绑定——不确定。
请检查 $setViewValue 的文档,显然在 ngModelValue 更新之前使用了 $validators。
你的范围。$watch 只会在 $modelValue 更新后被调用。
https://docs.angularjs.org/api/ng/type/ngModel.NgModelController#$setViewValue
调用 $setViewValue 时,将暂存新值以通过 $parsers 和 $validators 管道提交。如果没有指定特殊的 ngModelOptions 则暂存值将直接发送以通过 $parsers 管道进行处理。 在 之后,调用 $validators 和 $asyncValidators 并将值应用于 $modelValue。最后,该值设置为 ng-model 属性中指定的表达式,并调用 $viewChangeListeners 列表中所有已注册的更改侦听器。
我正在尝试使用自定义验证器创建一个 AngularJS 指令,以便我可以根据验证器显示错误消息。但是,我 运行ning 出错了,因为根据我输入的 console.log() 消息,验证器似乎在范围之前 运行ning。$watch() 。
指令如下:
angular
.module('app')
.directive('validateRefundAmount', validateRefundAmount);
validateRefundAmount.$inject = [ 'AmountConversionService', '$q' ];
function validateRefundAmount(AmountConversionService, $q) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, control) {
scope.$watch('orderDetails.refundAmount', function(newValue, oldValue) {
if (newValue === oldValue) {
console.log(newValue, oldValue);
return;
}
// Get Already Refunded Amount
var refundedAmount = scope.orderDetails.refundedAmount;
// Converts Amount To Pure Integers, Removing Decimal
var totalPaymentAmount = AmountConversionService.prepareAmountForCalculations(scope.orderDetails.paymentAmount, 10);
var totalRefundAmount = AmountConversionService.prepareAmountForCalculations(newValue || 0);
// Add Already Refunded Amount to Previously Refunded Amount to Get Total Refund
if (refundedAmount) {
totalRefundAmount += AmountConversionService.prepareAmountForCalculations(refundedAmount);
}
control.$validators.refundAmountTooHigh = function() {
if (totalRefundAmount > totalPaymentAmount) {
return false
}
return true;
}
});
}
};
}
应用的元素是一个没有值开头的文本输入框。当我在字段中键入“1”时,验证器不会 运行。当我在字段中添加一个“2”,生成“12”时,验证器 运行s 将“1”作为输入。当我将“3”添加到字段“123”时,也会发生同样的事情——它 运行s 为“12”,而不是新值“123”。
当我插入 console.log() 语句以查看发生了什么时,它看起来像验证程序代码 运行s 然后 scope.watch() 运行s 在验证器 运行 之后创建新值,但我不知道为什么或要搜索什么才能找到答案。
可能还有另一种方法可以做我想做的事情——我想做的是 运行 每次元素值改变时验证器。由于按键未检测到退格键,我无法在按键上使用绑定,也许可以在按键上使用绑定——不确定。
请检查 $setViewValue 的文档,显然在 ngModelValue 更新之前使用了 $validators。
你的范围。$watch 只会在 $modelValue 更新后被调用。
https://docs.angularjs.org/api/ng/type/ngModel.NgModelController#$setViewValue
调用 $setViewValue 时,将暂存新值以通过 $parsers 和 $validators 管道提交。如果没有指定特殊的 ngModelOptions 则暂存值将直接发送以通过 $parsers 管道进行处理。 在 之后,调用 $validators 和 $asyncValidators 并将值应用于 $modelValue。最后,该值设置为 ng-model 属性中指定的表达式,并调用 $viewChangeListeners 列表中所有已注册的更改侦听器。