在Angular 1.2和1.3之间,ngModelController解析管道的行为似乎已更改。现在,我总是看到一个名为'parse'$ 的新验证密钥添加到所有$error对象,并且只要其中一个解析器返回undefined,它就会覆盖/替换所有可能已经设置的其他验证密钥。
'parse'
$error
例如,这是Angular 1.2.23中的一个有效示例-尝试输入超出范围的数字:
http://jsfiddle.net/8doq0saf/5/
在1.3-rc下运行的同一事物会产生不同的结果:
http://jsfiddle.net/1t52s9b2/4/
我尚未找到有关此更改的任何文档。解析键的目的是什么,如何更改代码以恢复旧的行为?
angular.module('app', []).directive('number', function () { return { require: 'ngModel', link: function (scope, elem, attrs, ctrl) { // valid number ctrl.$parsers.push(function (value) { var valid = angular.isUndefined(value) || value === '' || isFinite(value); ctrl.$setValidity('number', valid); return valid ? angular.isUndefined(value) || value === '' ? undefined : Number(value) : undefined; }); ctrl.$parsers.push(function (value) { if (!angular.isDefined(attrs.minNumber)) { return value; } var valid = angular.isUndefined(value) || Number(value) >= Number(attrs.minNumber); ctrl.$setValidity('minNumber', valid); return valid ? value : undefined; }); ctrl.$parsers.push(function (value) { if (!angular.isDefined(attrs.maxNumber)) { return value; } var valid = angular.isUndefined(value) || Number(value) <= Number(attrs.maxNumber); ctrl.$setValidity('maxNumber', valid); return valid ? value : undefined; }); } }; });
Angular 1.3使事物合理化,从而在 解析 和 验证 之间进行了清晰的区分。
Angular现在会自动向所有$error集合添加一个“解析”键,并相应地设置其值- true如果返回任何解析器undefined,false则返回。
true
undefined
false
对于无法解析的值(为数字输入的字母,格式错误的日期等),我们应该undefined从解析器返回。这将导致Angular删除$error已设置的所有键,并用just替换整个对象{ "parse": true }。不再运行解析器。该模型将不会更新。$parsers现在,该数组仅应用于解析。
{ "parse": true }
$parsers
ngModelController具有一个新$validators属性,我们可以向其分配验证功能。这些仅在解析管道成功的情况下运行。从这些函数之一返回false,以获取可解析为所需数据类型的值,但仅是无效的(字符串太长,数字超出范围等)。验证器函数的名称成为$error对象中的验证键。即使一个返回,也将运行所有验证器false。仅当验证成功后,才会更新模型。
$validators
这可能是现有应用程序的重大变化,因为人们经常undefined从解析器返回无效值。这是我所拥有的,这是一个典型的示例:
ctrl.$parsers.push(function (value) { if (!angular.isDefined(attrs.minNumber)) { return value; } var valid = angular.isUndefined(value) || Number(value) >= Number(attrs.minNumber); ctrl.$setValidity('minNumber', valid); return valid ? value : undefined; });
在这种新方案下,应将其移至验证功能:
ctrl.$validators.minNumber = function (value) { return !value || !angular.isDefined(attrs.minNumber) || (value >= Number(attrs.minNumber)); });
这是已修复所有问题的指令:
angular.module('app', []).directive('number', function () { return { require: 'ngModel', link: function (scope, elem, attrs, ctrl) { // valid number ctrl.$parsers.push(function (value) { if(value === '') return value; return isFinite(value) ? Number(value) : undefined; }); ctrl.$validators.minNumber = function (value) { return !value || !angular.isDefined(attrs.minNumber) || (value >= Number(attrs.minNumber)); }; ctrl.$validators.maxNumber = function (value) { return !value || !angular.isDefined(attrs.maxNumber) || (value <= Number(attrs.maxNumber)); }; } }; });
http://jsfiddle.net/snkesLv4/10/
我真的很喜欢这种新方法-它更清洁。