在自定义验证器的范围更改时触发验证

Trigger validation on custom validator's scope change

假设我们有一个自定义验证器,其输入作为属性值。

app.directive('inputRequired', function() {
    return {
        require: 'ngModel',
        scope: {
            inputRequired: '='
        },
        link: function(scope, elm, attrs, ctrl) {
            ctrl.$validators.inputRequired = function(modelValue) {
                return !(scope.inputRequired && ctrl.$isEmpty(modelValue));
            };
        }
    };
});

在作用域上,我们定义了一个变量和一个函数来切换变量的值:

$scope.isRequired = false;

$scope.toggle = function() {
    $scope.isRequired = !$scope.isRequired;
};

然后我们创建一个表单,我们将在其中使用自定义验证器。我们也添加了一个按钮来调用切换功能。

<form>
    <input type="text" ng-model="someModel" input-required="isRequired"/>
    <button ng-click="toggle()">toggle</button>
</form>

这应该如何工作?当加载表单并初始化范围时,isRequired 的值设置为 false。因此不需要输入字段。当我们单击切换按钮时,isRequired 的值更改为 true。但!尽管更改了验证器范围内的变量,但未触发验证。

重要提示:这只是一个例子。我知道实现此功能的 ng-required 指令。当验证器有输入并且字段的有效性取决于该输入时,我需要一个通用的解决方案。如果输入更改,则必须立即重新验证该字段。

刚找到一个解决方案:在 link 函数的作用域上添加一个观察器,并在 inputRequired 更改时调用 $validate:

app.directive('inputRequired', function() {
    return {
        require: 'ngModel',
        scope: {
            inputRequired: '='
        },
        link: function(scope, elm, attrs, ctrl) {
            ctrl.$validators.inputRequired = function(modelValue) {
                return !(scope.inputRequired && ctrl.$isEmpty(modelValue));
            };

            scope.$watch("inputRequired", function() {
                ctrl.$validate(); 
            });
        }
    };
});