Cannot Find Control with Path Using ngIf on Recursive Angular Form

自作多情 提交于 2020-06-27 16:47:29

问题


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: Holds the main form with ng-containers and *ngFor to iterate over the groups

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: Holds the logic of the conditions items

And there is an ActionsButtonsBarComponent to hold the buttons to emit events, add, and remove the groups and conditions.

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.

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>

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.

So far, I have tried changing the FormGroupName many times to groups, statements, i, index, resulting in no improvement.

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.


回答1:


Stackblitz demo

Let's replace groupInstance for showConjunctor just to make it more obvious in what it's there for.

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'm considering that i, in the above snippet, is the index of the current loop in *ngFor (like in the Stackblitz demo).

Also, remove this part from the app.component.html:

<div *ngIf="i > 0">
  <div [formGroupName]="i">
    <input type="text" formControlName="conjunctor">
  </div>
</div>


来源:https://stackoverflow.com/questions/62585491/cannot-find-control-with-path-using-ngif-on-recursive-angular-form

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!