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

时间:2016-06-02 02:26:25

标签: validation angular formbuilder

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

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

现在,当我运行并提供已经存在于db中的用户名时,'result'变量的值我得到false,这是预期的和正确的。但是没有显示验证错误消息。我能够运行并获得其他自定义验证功能的验证错误消息。我正在使用Angular 2.0.0-beta.15。有人可以帮我理解可能出现的问题吗?

2 个答案:

答案 0 :(得分: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()

答案 1 :(得分:0)

如果你看一下这个 -

X=view_xview[0];
Y=view_yview[0];
if mouse_check_button(mb_left){
global.DRAG=true;
window_set_cursor(cr_drag);
view_xview-=vmx;
view_yview-=vmy;
}

/*else{
if !keyboard_check(vk_space){
    global.DRAG=false
}
window_set_cursor(cr_default);
}
*/
vmx=(mouse_x-X)-omx;
omx=(mouse_x-X);
vmy=(mouse_y-Y)-omy;
omy=(mouse_y-Y);

if mouse_wheel_up(){
center_of_space_x=view_xview+view_wview/2;
center_of_space_y=view_yview+view_hview/2;
view_wview-=view_wview*0.15;
view_hview-=view_hview*0.15;
view_xview=center_of_space_x-view_wview/2;
view_yview=center_of_space_y-view_hview/2;

}
if mouse_wheel_down(){
center_of_space_x=view_xview+view_wview/2;
center_of_space_y=view_yview+view_hview/2;
view_wview+=view_wview*0.15;
view_hview+=view_hview*0.15;
view_xview=center_of_space_x-view_wview/2;
view_yview=center_of_space_y-view_hview/2;
}

- 您可以看到我一起使用同步和异步验证。当我更改checkUserName的方法而不是'userName': ['', Validators.compose([Validators.required, ValidationService.checkUserName])] }); 方法时,会显示错误消息。