【问题标题】:Validation Error Message not getting displayed for custom validation in Angular 2Angular 2中的自定义验证未显示验证错误消息
【发布时间】:2023-03-11 03:32:01
【问题描述】:

我有一个注册表单,用户需要在其中提供用户名。当客户输入用户名时,如果该用户名已存在于数据库中,我想显示验证错误消息。

register.html

 <-- code here-->
<div class="form-group">
            <label for="username" class="col-sm-3 control-label">UserName</label>
            <div class=" col-sm-6">
             <input type="text" ngControl="userName" maxlength="45" class="form-control" [(ngModel)]="parent.userName" placeholder="UserName" #userName="ngForm" required data-is-unique/>
                <validation-message control="userName"></validation-message>
            </div>
        </div>
 <--code here-->

register.component.ts

import {Component} from 'angular2/core';
import {NgForm, FormBuilder, Validators, FORM_DIRECTIVES} from  'angular2/common';
   import {ValidationService} from '../services/validation.service';
  import {ValidationMessages} from './validation-messages.component';
  @Component({
    selector: 'register',
    templateUrl: './views/register.html',
    directives: [ROUTER_DIRECTIVES, ValidationMessages, FORM_DIRECTIVES],
    providers: []
   })
  export class ParentSignUpComponent {
   parentSignUpForm: any;
   constructor(private _formBuilder: FormBuilder) {
    this._stateService.isAuthenticatedEvent.subscribe(value => {
        this.onAuthenticationEvent(value);
    });
    this.parent = new ParentSignUpModel();
    this.parentSignUpForm = this._formBuilder.group({
        'firstName': ['', Validators.compose([Validators.required, Validators.maxLength(45), ValidationService.nameValidator])],
        'middleName': ['', Validators.compose([Validators.maxLength(45), ValidationService.nameValidator])],
        'lastName': ['', Validators.compose([Validators.required, Validators.maxLength(45), ValidationService.nameValidator])],
        'userName': ['', Validators.compose([Validators.required, ValidationService.checkUserName])]
    });
}
}

validation-message.component

import {Component, Host} from 'angular2/core';
import {NgFormModel} from 'angular2/common';
import {ValidationService} from '../services/validation.service';

@Component({
   selector: 'validation-message',
   inputs: ['validationName: control'],
   template: `<div *ngIf="errorMessage !== null" class="error-message"> {{errorMessage}}</div>`
    })
     export class ValidationMessages {
    private validationName: string;
    constructor (@Host() private _formDir: NgFormModel) {}
    get errorMessage() {
    let control = this._formDir.form.find(this.validationName);
    for (let propertyName in control.errors) {
        if (control.errors.hasOwnProperty(propertyName) && control.touched)   {
            return ValidationService.getValidatorErrorMessage(propertyName);
        }
      }
    return null;
  }
 }

validation-service.ts

  import {Injectable, Injector} from 'angular2/core';
  import {Control} from 'angular2/common';
  import {Observable} from 'rxjs/Observable';
  import {Http, Response, HTTP_PROVIDERS} from 'angular2/http';
  import 'rxjs/Rx';       
  interface ValidationResult {
    [key:string]:boolean;
    }
 @Injectable()
 export class ValidationService {
   static getValidatorErrorMessage(code: string) {
    let config = {
      'required': 'This field is required!',
      'maxLength': 'Field is too long!',
      'invalidName': 'This field can contain only alphabets, space, dot, hyphen, and apostrophe.',
      'userAlreadyInUse': 'UserName selected already in use! Please try another.'
};
return config[code];
}
static checkUserName(control: Control): Promise<ValidationResult> {
    let injector = Injector.resolveAndCreate([HTTP_PROVIDERS]);
    let http = injector.get(Http);
    let alreadyExists: boolean;
    if (control.value) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            http.get('/isUserNameUnique/' + control.value).map(response => response.json()).subscribe(result => {
                if (result === false) {
                    resolve({'userAlreadyInUse': true});
                } else {
                    resolve(null);
                }
            });
        }, 1000);
    });
    }
}
 }

现在,当我运行并提供数据库中已经存在的用户名时,我得到的“结果”变量的值是假的,这是预期的和正确的。但是没有显示验证错误消息。我能够运行并获取其他自定义验证功能的验证错误消息。我正在使用 Angular 2.0.0-beta.15。有人可以帮助我了解可能是什么问题吗?

【问题讨论】:

    标签: validation angular formbuilder


    【解决方案1】:

    异步验证存在一些已知问题


    这段代码可以简化

      return new Promise((resolve, reject) => {
        setTimeout(() => {
          http.get('/isUserNameUnique/' + control.value).map(response => response.json())
          .subscribe(result => {
            if (result === false) {
              resolve({'userAlreadyInUse': true});
            } else {
              resolve(null);
            }
          });
        }, 1000);
      });
    

      return http.get('/isUserNameUnique/' + control.value).map(response => response.json())
      .timeout(200, new Error('Timeout has occurred.'));
      .map(result => {
        if (result === false) {
          resolve({'userAlreadyInUse': true});
        } else {
          resolve(null);
        }
      }).toPromise();
    

    不要忘记导入 maptimeouttoPromise

    如果您在调用方站点上使用subscribe() 而不是then(),那么您可以省略toPromise() 事件

    【讨论】:

    • return http.get('/isUserNameUnique/' + control.value).map(response => response.json()) .timeout(200, new Error('超时已发生') ); .subscribe(result => { if (result === false) { resolve({'userAlreadyInUse': true}); } else { resolve(null); } });你是这个意思吗?因为我当时看不到或订阅您的代码。感谢您让我了解有关此问题的更多信息。我正在浏览链接,但没有得到任何提示。
    • thensubscribe 需要被 checkUserName checkUserName(c).then(...)checkUserName(c).subscribe(...) 的调用者使用。这就是 Angular 表单对异步验证器所做的事情(我不知道异步验证器是否需要返回 Promise 或者它们是否也可以与 Observable 一起使用)
    • 我的问题解决了。这不是因为那个 checkUserName 方法。如果你调查一下 - 'userName': ['', Validators.compose([Validators.required, ValidationService.checkUserName])] }); -- 你可以看到我同时使用同步和异步验证。当我更改 checkUserName 的方法(如 'Validators.composeAsync(ValidationService.checkUserName)' 而不是 Validators.compose 方法时,会显示错误消息。 :)
    • 太好了,感谢您的反馈。只需将此作为答案发布并接受它,以表明该问题已得到回答和解决。
    【解决方案2】:

    如果你调查一下 -

    'userName': ['', Validators.compose([Validators.required, ValidationService.checkUserName])] });
    

    -- 你可以看到我同时使用同步和异步验证。当我将 checkUserName 的方法更改为 'Validators.composeAsync(ValidationService.checkUserName)' 而不是 Validators.compose 方法时,会显示错误消息。

    【讨论】:

      猜你喜欢
      • 2016-07-23
      • 1970-01-01
      • 2018-02-08
      • 1970-01-01
      • 2018-08-09
      • 1970-01-01
      • 1970-01-01
      • 2015-09-07
      • 1970-01-01
      相关资源
      最近更新 更多