简体   繁体   English

提交后如何在Angular中异步验证表单?

[英]How to asynchronously validate form in Angular after submit?

I have a registration form validating client-side that works fine. 我有一个验证客户端的注册表格,工作正常。 My app has also a server-side validation which returns the client a JSON with errors for each field. 我的应用程序还有一个服务器端验证,它为客户端返回一个JSON,每个字段都有错误。

I try to handle them like this: 我试着像这样处理它们:

// errors = { 
//    "username": [
//        "Account 'test2@test.com' already exist!"
//    ]
// };

for(var field in errors) {
  $scope.RegForm.$setValidity(field, false);
  $scope.RegForm[field].$error.server = errors[field].join('\n');
}

The problem is that errors remain visible even when I change field. 问题是,即使我改变字段,错误仍然可见。 I need to set validity back to true, and remove server error at some moment. 我需要将有效性设置为true,并在某个时刻删除服务器错误。 Just not sure how and when. 只是不确定如何以及何时。

How to properly treat server data in order to make them change? 如何正确处理服务器数据以使其更改? $asyncValidators will not work, because in the case of username field I'm not allowed to register user, just to see if such username is free. $ asyncValidators不起作用,因为在用户名字段的情况下我不允许注册用户,只是为了查看这样的用户名是否是免费的。

Try like this 试试这样吧

for (var field in errors) {
    $timeout(function(){
        $scope.RegForm.$setValidity(field, false);
        $scope.RegForm[field].$error.server = errors[field].join('\n');
    });
}

Based on the responses suggested in AngularJS - Server side validation and client side forms , we create a directive that will reset the validation after changing the properties of the model. 根据AngularJS中建议的响应- 服务器端验证和客户端表单 ,我们创建一个指令,在更改模型的属性后重置验证。

Live example on jsfiddle . jsfiddle上的实时示例。

 angular.module('ExampleApp', ['ngMessages']) .controller('ExampleController', function($scope, ServerService) { $scope.user = {}; $scope.doSubmit = function(myForm) { ServerService.save().then(function(errors) { // Set error from server on our form angular.forEach(errors, function(error) { myForm[error.fieldName].$setValidity(error.error, false); }); }); }; }) //Simulate Ajax call .service('ServerService', function($q, $timeout) { var errorsFromServer = [{ fieldName: "firstName", error: "serverError" }, { fieldName: "lastName", error: "serverError" }, { fieldName: "email", error: "serverError" }, { fieldName: "email", error: "serverError2" }]; return { save: function() { return $q.when(errorsFromServer); } }; }) .directive('serverValidation', function() { return { restrict: "A", require: "ngModel", scope: { ngModel: "=", serverValidation: "=" // String or array of strings with name of errors }, link: function(scope, elem, attr, ngModelCtrl) { function setValidity(errorName) { console.log(errorName); ngModelCtrl.$setValidity(errorName, true); } if (typeof(scope.serverValidation) == "string") { console.log(scope.serverValidation); scope.arrServerValidation = [scope.serverValidation]; } else { scope.arrServerValidation = scope.serverValidation; } var firstError = scope.arrServerValidation[0]; scope.$watch('ngModel', function() { // workaround to don't update $setValidity, then changed value of ngModel // update $setValidity, only when server-error is true if (firstError && ngModelCtrl.$error[firstError]) angular.forEach(scope.arrServerValidation, setValidity); }); }, }; }); 
 .error { color: red; font-style: italic; } 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-messages.min.js"></script> <div ng-app="ExampleApp"> <div ng-controller="ExampleController"> <ng-form name="myForm"> <input ng-model="user.firstName" name="firstName" required server-validation="'serverError'"> <div ng-messages="myForm.firstName.$error" class="error"> <div ng-message="required">firstName is required</div> <div ng-message="serverError">firstName is server error</div> </div> <input ng-model="user.lastName" name="lastName" required server-validation="'serverError'"> <div ng-messages="myForm.lastName.$error" class="error"> <div ng-message="required">lastName is required</div> <div ng-message="serverError">lastName is server error</div> </div> <input ng-model="user.email" name="email" required server-validation="['serverError','serverError2']"> <div ng-messages="myForm.email.$error" class="error" multiple="true"> <div ng-message="required">email is required</div> <div ng-message="serverError">email is server error</div> <div ng-message="serverError2">email is server error 2</div> </div> <input ng-disabled="myForm.$invalid" ng-click="doSubmit(myForm)" type="submit"> </ng-form> </div> </div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM