Angular 1.3中新内置的"解析"验证密钥的目的是什么?

Mik*_*ain 10 validation angularjs angular-ngmodel

在Angular 1.2和1.3之间,ngModelController解析管道的行为似乎已经发生了变化.我现在总是看到一个新的名为确认键'parse'添加到所有$error对象,每当解析器之一返回undefined,它会覆盖/替换可能已设置的所有其他验证密钥.

例如,这是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;
            });
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

Mik*_*ain 29

Angular 1.3使事情合理化,以便在解析验证之间做出明确的区分.

解析

现在角度自动添加"解析"键,将所有$error与它的收藏价值相应地设置- true如果任何解析器的返回undefined,false否则.

对于不可解析的值(为数字输入的字母,格式错误的日期等),我们应该undefined从解析器返回.这将导致Angular删除$error已设置的任何键,并用just替换整个对象{ "parse": true }.不再运行解析器.该模型将不会更新.$parsers现在,该数组应仅用于解析.

验证

ngModelController有一个新$validators属性,我们可以为其分配验证功能.只有在解析管道成功时才会运行这些.从这些函数之一返回false,以获得可解析为所需数据类型的值,但只是无效(字符串太长,数字超出范围等).验证器函数的名称将成为$error对象中的验证密钥.即使有人返回,也会运行所有验证器false.只有在验证成功时才会更新模型.

这可能是现有应用程序的重大变化,因为人们经常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;
});
Run Code Online (Sandbox Code Playgroud)

在这个新方案下,这应该转移到验证功能:

ctrl.$validators.minNumber = function (value) {
    return !value || !angular.isDefined(attrs.minNumber) || (value >= Number(attrs.minNumber));
});
Run Code Online (Sandbox Code Playgroud)

以下是修正所有内容的指令:

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));
            };
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/snkesLv4/10/

我真的很喜欢这种新方式 - 它更清洁.

  • 实际上你应该使用新的`$ validators`管道来处理你的例子.`ctrl.$ validators.minNumber = function(val){/*...*/}` (2认同)