首页 > 解决方案 > 使用 *ngTemplateOutlet 的条件渲染在 formGroup 中无法正常工作

问题描述

我构建了一个可重用的表单输入,应该使用父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

标签: angularrxjsangular-reactive-formsform-controlng-template

解决方案


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只用and替换所有代码,null用于取消formGroupName不相关的(删除所有模板和东西):

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

推荐阅读