使用* ngTemplateOutlet的条件渲染无法在formGroup内正常工作

时间:2020-01-14 08:29:05

标签: angular rxjs angular-reactive-forms form-control ng-template

我构建了一个可重用的表单输入,应该使用父项formGroupName或作为常规输入控件呈现在表单内部。

我的代码如下:

child.component.html

 <ng-container *ngIf="hasFormGroup; then formFieldWithGroupName else formField">
 </ng-container>

<ng-template #formFieldWithGroupName>
   <span>control With Group Name</span>
   <div formGroupName="_general">
     <ng-container *ngTemplateOutlet="formField"></ng-container>

     <!-- MY ISSUE HERE: directly add the template below works but not best practice -->
     <!-- <input matInput placeholder="Project name" 
                          [formControlName]="controlName">  -->
   </div>
</ng-template>

<ng-template #formField>
   <span>control Without Group Name</span><br>
   <input matInput placeholder="Project name" 
                   [formControlName]="controlName"> 
</ng-template>

child.component.ts

import { Component, OnInit, Input } from '@angular/core';
import { FormControl, FormGroup, ControlContainer, FormGroupDirective, Validators, FormBuilder, NgModel } from '@angular/forms';
@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css'],
  viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }]
})
export class ChildComponent implements OnInit {

  childForm;
  @Input() hasFormGroup: boolean = false;
  @Input() controlName: string;
  constructor(private parentF: FormGroupDirective) { }

  ngOnInit() {
    this.childForm = this.parentF.form;

    if(this.hasFormGroup) {
      this.childForm.controls._general.addControl(this.controlName, new FormControl());
    } else {
      this.childForm.addControl(this.controlName, new FormControl())
    }
  }

}

以及父组件 app.component.html

的内容
<form [formGroup]="parentForm">
  <app-child [controlName]="'projectName'" [hasFormGroup]="false"></app-child>
  <app-child [controlName]="'projectName'" [hasFormGroup]="true"></app-child>
  <br>
  <hr>
  <app-child-2></app-child-2>

  Form Value: {{parentForm.value | json}}
</form>

组内的控件无法正常工作。但是,如果我直接使用模板(不使用ngTemplateOutlet进行渲染),则可以正确获取两个值。

有人可以帮助我找出为什么它不起作用吗?

调试呈现的元素表明所有指令均已呈现。

这是Stackblitz演示:

https://stackblitz.com/edit/angular-form-magic-4k6m9h

1 个答案:

答案 0 :(得分:0)

input控件无法获得其父级,因为它是在没有上下文的情况下注入的。将引用放入模板中,以便该指令在查找时可以看到它:

<ng-template #formField>
  <div formGroupName="_general">
    <span>control Without Group Name</span><br>
    <input matInput placeholder="Project name" 
                    [formControlName]="controlName"> 
  </div>
</ng-template>

好吧,编辑

仅用input替换所有代码,并在不相关时使用null取消formGroupName(删除所有模板和内容):

<div [formGroupName]="hasFormGroup ? '_general' : null">
  <input matInput placeholder="Project name" 
                  [formControlName]="controlName">
</div>