AngularJS摘要周期错误,ngmodel在自定义验证时被删除

AngularJS digest cycle bug, ngmodel wiped on custom validation

本文关键字:验证 自定义 删除 ngmodel 周期 错误 AngularJS      更新时间:2024-01-11

作为AngularJS的新手,我在为下拉选择编写自定义验证时遇到了一个非常奇怪的错误。

正如你所料,我已经用写下了这个下拉列表

<select name="somename" id="someid" ng-model="foo" ng-model-options="{allowInvalid: true}"  validate-input>
 <option></option> 
 <option></option>
</select>

在这种情况下,验证输入是我的自定义指令。它是这样写的:

directives.directive("validateInput", function () {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, ele, attrs, ctrl) {
            ctrl.$validators.isAcceptable = function (value) {
                var status = false;
                if (value === '0') {
                    status = true;
                }
                return status;
            };
        }
    }
});

在本例中,isAcceptable是我正在创建的标志。

无论如何,对于实际问题本身。每当我启动应用程序时,我都会发现ng模型的实际值被"擦除"了。也就是说,它要么是未知的,要么是NaN(当然取决于输入)。为了解决这个问题,我在select标记中放入了以下指令:ng model options="{allowInvalid:true}然而,这并没有解决我的问题。

这个问题之所以如此严重,是因为当ng模型被错误验证(设置为NaN或未知)擦除时,这会导致我的应用程序稍后出现重大错误。我能得到的唯一解决方案是使ng model="0"或="(这是一个错误的验证)并保留这些值,而不是从应用程序中删除模型本身。

试试这样的东西:

directives.directive("validateInput", function () {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, ele, attrs, ctrl) {
            ctrl.$validators.isAcceptable = function (modelValue, viewValue) {
                var value = modelValue || viewValue;
                return value === '0' ? true : false;
            };
        }
    }
});

仅当viewValue满足验证条件时才设置modelValue。因此,在init中它是空白的,另一个验证器可能会阻止它设置值。

你可能完全想使用这种格式:

directives.directive("validateInput", function () {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, ele, attrs, ctrl) {
            var setValidator = function (value) {
                var isValidFormat = function () {
                    return $value === '0' ? true : false;
                };
                ctrl.$setValidity('isAcceptable', isValidFormat);
                return value;
            };
            ctrl.$parsers.unshift(setValidator);
            ctrl.$formatters.unshift(setValidator);
        }
    }
});