Angular FormGroup如何将带formControlName的ng-template移到表单外
问题原因
两次报错的核心原因是传递的表单层级不对:
- 第一次把
ng-template移到表单外时,模板脱离了内部formGroup/formArrayName的上下文树,formControlName找不到上级的表单指令,所以报必须和父formGroup指令配合使用的错误。 - 第二次传参时传入的是最外层的根
Form实例,但content控件并不直接挂载在根表单下,它的完整路径是根FormGroup -> things FormArray -> 对应索引的子FormGroup -> content FormControl,直接在根表单下查找content控件自然会报找不到的错误。
正确实现方案
方案1:传递对应层级的子FormGroup
你在*ngFor中循环的item本身就是things表单数组对应索引项的子FormGroup,直接把这个实例传给模板即可,不要传根Form:
表单内部调用模板部分
<form id="list" [formGroup]="Form"> <ion-list lines="none" class="list"> <ion-item-sliding formArrayName="things" *ngFor="let item of formArray.controls; index as index"> <ion-item [formGroupName]="index"> <ng-container [ngTemplateOutlet]="thingText" [ngTemplateOutletContext]="{ group: item, index: index }"> </ng-container> </ion-item> </ion-item-sliding> </ion-list> </form>
移到表单外部的ng-template
<ng-template #thingText let-group="group" let-index="index"> <!-- 绑定传入的对应层级的子FormGroup --> <div [formGroup]="group"> <ion-textarea id="thing-text" formControlName="content" auto-grow (click)="activateEditing(index)" (ionBlur)="leaveTheField(index)" (keypress)="detectChange(index)" (ionFocus)="changeScroll(index)" #activeThings> </ion-textarea> </div> </ng-template>
注意:响应式表单不需要手动加
value="{{ item.value.content }}"绑定,formControlName本身会自动同步控件值,手动加value属性反而可能造成值不同步问题。
方案2:直接传递FormControl实例(更简单,无需维护表单层级)
不需要在模板里嵌套绑定FormGroup,直接把需要绑定的content控件实例传给模板,用[formControl]直接绑定即可,完全不会出现层级匹配错误:
表单内部调用模板部分
<ng-container [ngTemplateOutlet]="thingText" [ngTemplateOutletContext]="{ control: item.get('content'), index: index }"> </ng-container>
外部ng-template实现
<ng-template #thingText let-control="control" let-index="index"> <ion-textarea id="thing-text" [formControl]="control" auto-grow (click)="activateEditing(index)" (ionBlur)="leaveTheField(index)" (keypress)="detectChange(index)" (ionFocus)="changeScroll(index)" #activeThings> </ion-textarea> </ng-template>
内容的提问来源于stack exchange,提问作者João Otero
相关产品推荐
相关产品推荐

