Angular 中的自定义验证未显示验证错误消息 2

Validation Error Message not getting displayed for custom validation in Angular 2

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

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])]
    });
}
}

验证-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;
  }
 }

验证-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);
    });
    }
}
 }

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

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


这段代码可以简化

  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()

如果你调查这个 -

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

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