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