首页 文章

如何使用当前的Form API将父组件的FormGroup传递给其子组件

提问于
浏览
6

我想将父组件的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
        });
}
}

我现在想将表单: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/跟随这个过时的例子

3 回答

  • 0

    在父组件中执行此操作

    <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

  • 12

    这是父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>
    
  • 1

    我会将表单作为输入传递给子组件;

    @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>
    

相关问题