web-dev-qa-db-ja.com

現在のフォームAPIを使用して、親コンポーネントのFormGroupをその子コンポーネントに渡すにはどうすればよいですか

子を使用してエラーメッセージを表示するために、親コンポーネントのFormGroupを子に渡したい

次の親を考える

parent.cmponent.ts

import { Component, OnInit } from '@angular/core'
import {
    REACTIVE_FORM_DIRECTIVES, AbstractControl, FormBuilder, FormControl,
    FormGroup, Validators
} from '@angular/forms'

@Component(
    {
      moduleId: module.id,
      selector: 'parent-cmp',
      templateUrl: 'language.component.html',
      styleUrls: ['language.component.css'],
      directives: [
        ErrorMessagesComponent]
    })
export class ParentCmp implements OnInit {
  form: FormGroup;
  first: AbstractControl;
  second: AbstractControl;

  constructor(private _fb: FormBuilder) {
    this.first =
        new FormControl('');
    this.second = new FormControl('')
  }

  ngOnInit() {
    this.form = this._fb.group(
        {
          'first': this.first,
          'second': this.second
        });
}
}

次に、上のform:FormGroup変数を下の子コンポーネントに渡します

error-message.component.ts

import { Component, OnInit, Input } from '@angular/core'
import { NgIf } from '@angular/common'
import {REACTIVE_FORM_DIRECTIVES, FormGroup } from '@angular/forms'

@Component(
    {
      moduleId: module.id,
      selector: 'epimss-error-messages',
      template: `
   <span class="error" *ngIf="errorMessage !== null">{{errorMessage}}</span>`,
      styles: [],
      directives: [REACTIVE_FORM_DIRECTIVES, NgIf]

    })
export class ErrorMessagesComponent implements OnInit {
  @Input()
  ctrlName: string

  constructor(private _form: FormGroup) {
  }

  ngOnInit() {
      }

  get errorMessage() {
    // Find the control in the Host (Parent) form
    let ctrl = this._form.find(this.ctrlName);

    console.log('ctrl| ', ctrl)

//    for (let propertyName of ctrl.errors) {
//      // If control has a error
//      if (ctrl.errors.hasOwnProperty(propertyName) && ctrl.touched) {
//        // Return the appropriate error message from the Validation Service
//        return CustomValidators.getValidatorErrorMessage(propertyName);
//      }
//    }

    return null;
  }

コンストラクタformGroupは親のFormGroupを表します-現在のフォームでは機能しません。

私は http://iterity.io/2016/05/01/angular/angular-2-forms-and-advanced-custom-validation/ にあるこの時代遅れの例をフォローしようとしています。

8
st_clair_clarke

親コンポーネントでこれを行います

<div [formGroup]="form">
  <div>Your parent controls here</div>
  <your-child-component [FormGroup]="form"></your-child-component>
</div>

そして、子コンポーネントでそのような参照を取得できます...

export class YourChildComponent implements OnInit {
  public form: FormGroup;

  // Let Angular inject the control container
  constructor(private controlContainer: ControlContainer) { }

  ngOnInit() {
    // Set our form property to the parent control
    // (i.e. FormGroup) that was passed to us, so that our
    // view can data bind to it
    this.form = <FormGroup>this.controlContainer.control;
  }
}

そのようにセレクターを変更することで、formGroupNameまたは[formGroup]がコンポーネントに指定されていることを確認することもできます。

selector: '[formGroup] epimss-error-messages,[formGroupName] epimss-error-messages'

この答えはあなたのニーズには十分ですが、あなたがもっと知りたいのであれば、私はここにブログエントリを書きました

https://mrpmorris.blogspot.co.uk/2017/08/angular-composite-controls-formgroup-formgroupname-reactiveforms.html

11
Peter Morris

これは、親formGroup内で使用される子コンポーネントの例です。子コンポーネントts:

import { Component, OnInit, Input } from '@angular/core';
import { FormGroup, ControlContainer, FormControl } from '@angular/forms';


@Component({
  selector: 'app-date-picker',
  template: `
  <mat-form-field [formGroup]="form" style="width:100%;">
  <input matInput [matDatepicker]="picker" [placeholder]="placeHolder" [formControl]="control" readonly>
  <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
  <mat-datepicker #picker></mat-datepicker>
</mat-form-field>
<mat-icon (click)="clearDate()">replay</mat-icon>`,
  styleUrls: ['./date-picker.component.scss']
})

export class DatePickerComponent implements OnInit {
  public form: FormGroup;
  public control : FormControl;
  @Input() controlName : string;
  @Input() placeHolder : string;


  constructor(private controlContainer: ControlContainer) { 
  }

  clearDate(){
    this.control.reset();
  }

  ngOnInit() {
    this.form = <FormGroup>this.controlContainer.control;
    this.control = <FormControl>this.form.get(this.controlName);
    }

}

css日付ピッカー:

mat-icon{
position: absolute;
left: 83%;
top: 31%;
transform: scale(0.9);
cursor: pointer;
}

次のように使用します:

 <app-date-picker class="col-md-4" [formGroup]="feuilleForm" controlName="dateCreation" placeHolder="Date de création"></app-date-picker>
0
HMZ

フォームを入力として子コンポーネントに渡します。

@Component(
    {
      moduleId: module.id,
      selector: 'epimss-error-messages',
      template: `
   <span class="error" *ngIf="errorMessage !== null">{{errorMessage}}</span>`,
      styles: [],
      directives: [REACTIVE_FORM_DIRECTIVES, NgIf]

    })
export class ErrorMessagesComponent implements OnInit {
  @Input()
  ctrlName: string

  @Input('form') _form;

  ngOnInit() {
         this.errorMessage();
      }

  errorMessage() {
    // Find the control in the Host (Parent) form
    let ctrl = this._form.find(this.ctrlName);

    console.log('ctrl| ', ctrl)

//    for (let propertyName of ctrl.errors) {
//      // If control has a error
//      if (ctrl.errors.hasOwnProperty(propertyName) && ctrl.touched) {
//        // Return the appropriate error message from the Validation Service
//        return CustomValidators.getValidatorErrorMessage(propertyName);
//      }
//    }

    return null;
  }

そしてもちろん、フォームを親コンポーネントから子に渡す必要があります。これはさまざまな方法で行うことができますが、最も簡単な方法は次のとおりです。

あなたの親のどこかに

     <epimss-error-messages [form]='form'></epimss-error-messages>
0
Milad