当更改另一个字段时触发字段验证

时间:2022-09-26 11:52:07

I have a custom validation directive that is being called properly when one field is changed. However, whether this field is valid is also based on another field's value. This second field is a select list if that is of importance.

我有一个自定义验证指令,当一个字段被更改时,它会被正确地调用。然而,这个字段是否有效也是基于另一个字段的值。第二个字段是一个选择列表,如果它很重要的话。

I was wondering if there was some way I could trigger validation manually when the second form is changed. Perhaps by using the ng-change event. What is the proper way to handle something like this?

我想知道是否有什么方法可以在修改第二个表单时手动触发验证。也许是通过使用ng-change事件。处理这种事情的正确方法是什么?

Here is my directive:

这是我的指令:

angular.module('myApp', []).
    directive('validage', function () {
        return {
            require: 'ngModel',
            link: function (scope, elem, attr, ngModel) {

                function validate(value) {
                    var valid = true;
                    if ((GetDateDifference(new Date(value), new Date()) < 16 || GetDateDifference(new Date(value), new Date()) > 129)
                    && scope.dep.DependantType == "Spouse") {
                        valid = false;
                    }
                    ngModel.$setValidity('validage', valid);
                    return value;
                }

                //For DOM -> model validation
                ngModel.$parsers.unshift(function (value) {
                    var valid = true;
                    if ((GetDateDifference(new Date(value), new Date()) < 16 || GetDateDifference(new Date(value), new Date()) > 129)
                    && scope.dep.DependantType == "Spouse") {
                        valid = false;
                    }
                    ngModel.$setValidity('validage', valid);
                    return value;
                });

                //For model -> DOM validation
                ngModel.$formatters.unshift(function (value) {
                    var valid = true;
                    if ((GetDateDifference(new Date(value), new Date()) < 16 || GetDateDifference(new Date(value), new Date()) > 129)
                    && scope.dep.DependantType == "Spouse") {
                        valid = false;
                    }
                    ngModel.$setValidity('validage', valid);
                    return value;
                });
            }
        };
    });

If you're new to AngularJS, I would definitely recommend reading these 2 articles: part 1 & part 2. They are an overview of AngularJS forms.

如果你是AngularJS的新手,我绝对推荐阅读这两篇文章:第1部分和第2部分。它们是AngularJS格式的概述。

4 个解决方案

#1


46  

After searching a lot for this I've found that we can trigger validation simply by calling $validate() on the desired field.
So for example if your form is named my_form (i.e. in the markup the form tag has a name="my_form" attribute) and the name of the field you want to validate is date (in the markup the input field has a name="date" attribute), then as you suggested you can use the ng-change event of the second field and call $scope.my_form.date.$validate(); whenever the ng-change function is invoked.

在搜索了很多之后,我发现我们可以通过在所需的字段上调用$validate()来触发验证。举个例子,如果你的形式命名my_form(即标记形式标记的name = " my_form "属性)和字段的名称你想验证的是日期(在输入字段标记有一个名称=“日期”属性),那么建议你可以使用第二个字段的ng-change事件并调用scope.my_form.date。美元validate();无论何时调用ng-change函数。

#2


3  

I had a similar problem: two form fields "interval" (for $scope.monitor.interval) and "timeout" (for $scope.monitor.timeout) with the condition that timeout must not exceed half of interval.

我遇到了类似的问题:两个表单字段“interval”(用于$scope.monitor.interval)和“timeout”(用于$scope.monitor.timeout),条件是超时不能超过interval的一半。

First, I added a custom validator to timeout that checks for this condition. Now I needed to trigger the timeout validator also when interval changes. I achieved this by watching the monitor.interval property of the model:

首先,我向超时添加了一个自定义验证器,用于检查此条件。现在我还需要在间隔改变时触发超时验证器。我通过观察模型的monitor.interval属性实现了这一点:

function EditMonitorCtrl($scope, $log, dialog, monitor) {
    $scope.monitor = monitor;

    ...

    // trigger validation of timeout field when interval changes
    $scope.$watch("monitor.interval", function() {
        if ($scope.editMonitorDlg.timeout.$viewValue) {          
            $scope.editMonitorDlg.timeout.$setViewValue($scope.editMonitorDlg.timeout.$viewValue);
        }
    });
}

Without "if" the timeout value got removed during intialisation of the dialog.

如果没有“if”,则在对话框的初始化过程中删除了超时值。

#3


0  

I ended up adding the directive to the second field and then altering the directive to add the error message to the field with the error. There might be a better way, but that is what I ended up doing.

最后我将该指令添加到第二个字段,然后修改该指令,将错误消息添加到该字段。也许有更好的办法,但这就是我最后做的。

#4


0  

I was unable to get ng-blur="myForm.myField.$validate()" working in AngularJS 1.5, possibly because the model for myField was empty.

我无法让ng-blur="myForm.myField.$validate()"在AngularJS 1.5中工作,可能是因为myField的模型是空的。

However, ng-blur="myForm.myField.$setTouched()" did work.

然而,ng-blur = " myForm.myField。美元setTouched()所做的工作。

#1


46  

After searching a lot for this I've found that we can trigger validation simply by calling $validate() on the desired field.
So for example if your form is named my_form (i.e. in the markup the form tag has a name="my_form" attribute) and the name of the field you want to validate is date (in the markup the input field has a name="date" attribute), then as you suggested you can use the ng-change event of the second field and call $scope.my_form.date.$validate(); whenever the ng-change function is invoked.

在搜索了很多之后,我发现我们可以通过在所需的字段上调用$validate()来触发验证。举个例子,如果你的形式命名my_form(即标记形式标记的name = " my_form "属性)和字段的名称你想验证的是日期(在输入字段标记有一个名称=“日期”属性),那么建议你可以使用第二个字段的ng-change事件并调用scope.my_form.date。美元validate();无论何时调用ng-change函数。

#2


3  

I had a similar problem: two form fields "interval" (for $scope.monitor.interval) and "timeout" (for $scope.monitor.timeout) with the condition that timeout must not exceed half of interval.

我遇到了类似的问题:两个表单字段“interval”(用于$scope.monitor.interval)和“timeout”(用于$scope.monitor.timeout),条件是超时不能超过interval的一半。

First, I added a custom validator to timeout that checks for this condition. Now I needed to trigger the timeout validator also when interval changes. I achieved this by watching the monitor.interval property of the model:

首先,我向超时添加了一个自定义验证器,用于检查此条件。现在我还需要在间隔改变时触发超时验证器。我通过观察模型的monitor.interval属性实现了这一点:

function EditMonitorCtrl($scope, $log, dialog, monitor) {
    $scope.monitor = monitor;

    ...

    // trigger validation of timeout field when interval changes
    $scope.$watch("monitor.interval", function() {
        if ($scope.editMonitorDlg.timeout.$viewValue) {          
            $scope.editMonitorDlg.timeout.$setViewValue($scope.editMonitorDlg.timeout.$viewValue);
        }
    });
}

Without "if" the timeout value got removed during intialisation of the dialog.

如果没有“if”,则在对话框的初始化过程中删除了超时值。

#3


0  

I ended up adding the directive to the second field and then altering the directive to add the error message to the field with the error. There might be a better way, but that is what I ended up doing.

最后我将该指令添加到第二个字段,然后修改该指令,将错误消息添加到该字段。也许有更好的办法,但这就是我最后做的。

#4


0  

I was unable to get ng-blur="myForm.myField.$validate()" working in AngularJS 1.5, possibly because the model for myField was empty.

我无法让ng-blur="myForm.myField.$validate()"在AngularJS 1.5中工作,可能是因为myField的模型是空的。

However, ng-blur="myForm.myField.$setTouched()" did work.

然而,ng-blur = " myForm.myField。美元setTouched()所做的工作。