0

この記事に基づいてフォーム検証パターンを実装しようとしています: https://coryrylan.com/blog/angular-form-b​​uilder-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に投稿しました

ここで不足しているものについてご意見をいただければ幸いです。

前もって感謝します!

4

1 に答える 1

0

コンポーネントのテンプレートにある複数の errorMessage(s) 参照のタイプミスであることがわかりました。今朝スッキリ見てたら、やっと見れました。

見てくれた人ありがとう!

于 2017-01-04T15:20:11.827 に答える