この記事に基づいてフォーム検証パターンを実装しようとしています: https://coryrylan.com/blog/angular-form-builder-and- validation-management
検証自体は正常に機能していますが、検証メッセージを表示するコンポーネントはトリガーされません。コンストラクターがヒットするとインスタンス化されますが、「this.control」(コンポーネントに提供された入力値を参照する) は未定義です。
これはコンポーネント自体のコードです
import { Component, Input } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import { FormValidationService } from "./validation/formValidation.service";
@Component({
selector: 'form-control-messages',
template: `<div *ngIf="errorMessage !== null">{{errorMessage}}</div>`
})
export class FormControlMessagesComponent {
@Input() control: FormControl;
constructor(){ }
get errorMessages() {
for (let propertyName in this.control.errors) {
if(this.control.errors.hasOwnProperty(propertyName) && this.control.touched){
return FormValidationService.getValidatorErrorMessage(propertyName, this.control.errors[propertyName]);
}
}
return null;
}
}
.. 検証サービスのコード ..
export class FormValidationService {
static getValidatorErrorMessage(validatorName: string, validatorValue?: any) {
let messages = {
'required': 'This field is required.',
'invalidEmailAddress': 'This is not a valid email address.',
'minlength': `This must contain at least ${validatorValue.requiredLength} characters.`,
'invalidStateCode': 'This is not a valid state.',
'invalidPostalCode': 'This is not a valid postal code.',
};
return messages[validatorName];
}
// implementing a couple basic validations, again these can be segmented as needed
static emailValidtor(control){
// RFC 2822 compliant regex
if (control.value.match(/[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/)) {
return null;
}
else {
return { 'invalidEmailAddress': true };
}
}
static stateCodeValidator(control){
let validCodes = ['AK','AL','AR','AZ','CA','CO','CT','DC','DE','FL','GA','GU','HI','IA','ID', 'IL','IN','KS','KY','LA','MA','MD','ME','MH','MI','MN','MO','MS','MT','NC','ND','NE','NH','NJ','NM','NV','NY', 'OH','OK','OR','PA','PR','PW','RI','SC','SD','TN','TX','UT','VA','VI','VT','WA','WI','WV','WY'];
return (validCodes.indexOf(control.value) !== -1) ? null : { 'invalidStateCode' : true };
}
static postalCodeValidator(control){
console.log('validating postal code');
// note this will only match US five- and nine-digit codes
if(control.value.match(/^[0-9]{5}(?:-[0-9]{4})?$/)) {
return null;
}
else {
return { 'invalidPostalCode': true };
}
}
}
そして最後に、テストフォームのコンポーネントとテンプレート..
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { FormValidationService } from '../shared/validation/formValidation.service';
@Component({
selector: 'test-form',
templateUrl: 'testForm.component.html'
})
export class TestFormComponent {
testForm: FormGroup;
constructor(private fb: FormBuilder) {
this.testForm = this.fb.group({
setup: this.fb.group({
keyIdentifier: ['', [Validators.required, Validators.minLength(6)]],
keyType: [''],
}),
contactInformation: this.fb.group({
name: ['', Validators.required],
emailAddress: ['', [Validators.required, FormValidationService.emailValidator]],
postalCode: ['', [Validators.required, FormValidationService.postalCodeValidator]]
})
});
}
save(){
if(this.testForm.dirty && this.testForm.valid) {
// DO STUFF
}
}
}
<form [formGroup]="testForm" (submit)="save()">
<div formGroupName="setup">
<label for="keyIdentifier">Key ID:</label>
<input type="text" formControlName="keyIdentifier" id="keyIdentifier" />
<form-control-messages [control]="testForm.controls.setup.controls.keyIdentifier"></form-control-messages>
<label for="keyType">Key ID:</label>
<input type="text" formControlName="keyType" id="keyType" />
<form-control-messages [control]="testForm.controls.setup.controls.keyType"></form-control-messages>
</div>
<div formGroupName="contactInformation">
<label for="name">Name:</label>
<input type="text" formControlName="name" id="name" />
<form-control-messages [control]="testForm.controls.contactInformation.controls.name"></form-control-messages>
<label for="email">Email:</label>
<input type="email" formControlName="email" id="email" />
<form-control-messages [control]="testForm.controls.contactInformation.controls.email"></form-control-messages>
<label for="postalCode">Postal Code:</label>
<input type="text" formControlName="postalCode" id="postalCode" />
<form-control-messages [control]="testForm.controls.contactInformation.controls.postalCode"></form-control-messages>
</div>
<button type="submit">Save</button>
</form>
このすべてをhttp://plnkr.co/edit/rxvBLr5XtTdEUy5nGtAGに投稿しました
ここで不足しているものについてご意見をいただければ幸いです。
前もって感謝します!