在递归角度形式上无法使用ngIf找到带有路径的控件 [英] Cannot Find Control with Path Using ngIf on Recursive Angular Form
问题描述
这是下面代码的堆栈闪电.
我正在使用FormArrays和子组件制作一个相当复杂的深层嵌套Angular表单.在大多数情况下,一切都按预期进行. group
对象包含conjunctor
,conditions[]
和groups[]
. groups[]
是一个嵌套组,可以无限嵌套包含同一对象.
Here is the stackblitz for the code below.
I am making a fairly complex deeply nested Angular form using FormArrays, and child components. For the most part, everything is working as expected. A group
object contains a conjunctor
, conditions[]
, and groups[]
. groups[]
is a nested group that can be nested infinitely containing the same object.
当前,您可以选择添加组",添加嵌套组",添加条件",删除组"和删除条件".这样就可以制作一个嵌套的表单对象.为此,该应用程序分为三个部分:
Currently, you have the option to "add group", "add nested group", "add condition", "delete group", and "delete condition" so that it makes a nested form object. To do this, the app is split into 3 components:
AppComponent:持有带有ng-container
s和*ngFor
的主窗体以遍历组
AppComponent: Holds the main form with ng-container
s and *ngFor
to iterate over the groups
GroupControlComponent:保存AppComponent内部每个项目的逻辑,并与AppComponent进行相同的操作,只是针对条件和嵌套组
GroupControlComponent: Holds the logic of each item inside the AppComponent and does the same thing as the AppComponent but for Conditions and Nested Groups
ConditionsForm:保存条件项的逻辑
ConditionsForm: Holds the logic of the conditions items
并且有一个ActionsButtonsBarComponent来保存按钮以发出事件,添加和删除组和条件.
And there is an ActionsButtonsBarComponent to hold the buttons to emit events, add, and remove the groups and conditions.
我正在尝试在第二组中做到这一点,连接器有一个输入.我根本不需要第一个实例,因为我希望第一个实例始终为null.但是,在第2次及其后的实例中,我希望出现连接器输入,并提供选项为"AND"或"AND".或"OR".创建此代码时,出现错误:ERROR: Cannot find control with path: 'statement → groups → 1 → conjunctor
来自AppComponent.
I am trying to make it so on every second group, there is an input for the Conjunctor. I don't want it at all on the first instance since I want the first to always be null. However, on the 2nd and thereafter instances, I want the conjunctor input to appear giving the option to be either "AND" or "OR". As I create this, I am getting the error: ERROR: Cannot find control with path: 'statement → groups → 1 → conjunctor
coming from the AppComponent.
这是AppComponent的外观:
Here's how the AppComponent looks:
<form [formGroup]="_form">
<ng-container formGroupName="statement">
<ng-container formArrayName="groups">
<ng-container *ngFor="let group of _groupsFormArray?.controls; index as i">
<div *ngIf="i > 0">
<div [formGroupName]="i">
<input type="text" formControlName="conjunctor">
</div>
</div>
<app-group-control
(remove)="_delete(i)"
[formControlName]="i"
[formLabel]="'Group '+ (i + 1) + ':'">
</app-group-control>
</ng-container>
</ng-container>
</ng-container>
</form>
如您所见,有一个div
包含ngIf逻辑:
As you can see, there is a div
containing the ngIf logic:
<div *ngIf="i > 0">
<div [formGroupName]="i">
<input type="text" formControlName="conjunctor">
</div>
</div>
此方法不起作用,但是我尝试过的其他方法都没有.
This method is not working, but neither have the other methods I have tried.
到目前为止,我已经尝试过多次将FormGroupName更改为groups
,statements
,i
,index
,但没有任何改善.
So far, I have tried changing the FormGroupName many times to groups
, statements
, i
, index
, resulting in no improvement.
我还尝试使用@ViewChildren('templateRef') templateRefVar: QueryList<ElementRef>;
从AppComponent跟踪每个ngFor
的实例,然后使用模板引用#templateRef
跟踪ngFor
内部.从那里,我使用@Input() groupInstances
将此templateRef.length
传递给我的子组件GroupControlComponent
,然后在内部使用ngIf.这是我得到的最接近的问题,但是问题是,每当满足ngIf条件时,它就会出现在每个组数组实例(包括第一个)上,并且出现错误:ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '0'. Current value: '1'.
. 这里是使用此方法获得的最接近的StackBlitz .并且这是上述代码中的StackBlitz .
I have also tried tracking the instances of each ngFor
from the AppComponent using @ViewChildren('templateRef') templateRefVar: QueryList<ElementRef>;
and then inside the ngFor
, using a template ref #templateRef
. From there, I pass this templateRef.length
to my child component GroupControlComponent
using @Input() groupInstances
, and then using the ngIf inside. This is the closest I have gotten, but the problem is, every single time the ngIf condition is met, it appears on EVERY instance of the group arrays, including the first, as well as gives me the error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '0'. Current value: '1'.
. Here is a StackBlitz of the closest I've got using this method. And here is the StackBlitz from the code as of above.
如果您想查找有关此递归表格的更多信息,可以在此处了解有关此递归表格的信息.
If you'd like to find more about this recursive form, you can read about that here.
推荐答案
让groupInstance
替换为showConjunctor
只是为了使其在用途上更加明显.
Let's replace groupInstance
for showConjunctor
just to make it more obvious in what it's there for.
您可以在自己的 app.component.hml
中进行此操作:
You can do this in you app.component.hml
:
<app-group-control
#templateRef
(remove)="_delete(i)"
[formControlName]="i"
[formLabel]="'Group '+ (i + 1) + ':'"
[showConjunctor]="!((i + 1) % 2)">
</app-group-control>
我正在考虑上述片段中的i
是*ngFor
中当前循环的索引(就像Stackblitz演示中一样).
I'm considering that i
, in the above snippet, is the index of the current loop in *ngFor
(like in the Stackblitz demo).
另外,从app.component.html
删除此部分:
<div *ngIf="i > 0">
<div [formGroupName]="i">
<input type="text" formControlName="conjunctor">
</div>
</div>
[更新] :根据您的评论,如果您希望所有连接器中都包含连接器
您可以在GroupControlComponent
内将@Input() showConjuntor
设置为true(
[UPDATE]: Per your comments, if you want to have the conjunctor in all
of the nested Groups, you can set the @Input() showConjuntor
to true inside the GroupControlComponent
(Stackblitz demo):
<ng-container formArrayName="groups">
<app-group-control *ngFor="let s of _groupsFormArray?.controls; index as i"
(remove)="_deleteGroupFromArray(i)"
[formControlName]="i"
[formLabel]="'Nested Group '+ (i + 1) + ':'"
[showConjunctor]="true">
</app-group-control>
</ng-container>
这篇关于在递归角度形式上无法使用ngIf找到带有路径的控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!