小编典典

Angular 1.3中新内置的“ parse”验证密钥的目的是什么?

angularjs

在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;
            });
        }
    };
});

阅读 226

收藏
2020-07-04

共1个答案

小编典典

Angular 1.3使事物合理化,从而在 解析验证 之间进行了清晰的区分。

解析中

Angular现在会自动向所有$error集合添加一个“解析”键,并相应地设置其值-
true如果返回任何解析器undefinedfalse则返回。

对于无法解析的值(为数字输入的字母,格式错误的日期等),我们应该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;
});

在这种新方案下,应将其移至验证功能:

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/

我真的很喜欢这种新方法-它更清洁。

2020-07-04