0

I have a app-document-form-node component that recursive builds components.

Component app-document-form-node:

<ng-container *ngIf="block.type === fielType.Block">
    <app-adresat-list *ngIf="block.tag === 'ADRESATS'" [list]="block?.children"></app-adresat-list>
    <app-word-settings *ngIf="block.tag === 'WORD_SETTINGS'" [element]="block"></app-word-settings>
    <app-parameters *ngIf="block.tag === 'PARAMETERS'" [element]="block"></app-parameters>
    <app-document-parameters *ngIf="block.tag === 'GENERICPARAMETERS'" [element]="block"></app-document-parameters>
</ng-container>

<!----->

<ng-container *ngIf="block.type === fielType.Field">
    <app-field [ismultisignator]="properties?.ismultisignator" [fieldDefinition]="block" (onSelected)="onFieldSelected($event)"></app-field>
</ng-container>

<!----->

<ng-container *ngIf="block.type === fielType.Table">
    <app-postaddress *ngIf="block.tag === 'TAG_ADDR'" [element]="block"></app-postaddress>
</ng-container>

<!--------------->

<div class="children" *ngIf="block?.children && block.children.length">
    <ng-template ngFor let-child [ngForOf]="block.children">
        <app-document-form-node [block]="child" [properties]="properties"></app-document-form-node>
    </ng-template>
</div>

Problem is in section <ng-container *ngIf="block.type === fielType.Block"></ng-container>.

When it happends all children components should be placed in components <app-adresat-list, <app-word-settings>, <app-parameters>, app-document-parameters in case when block has children.

Now it works, but after all mentioned above components:

<div class="children" *ngIf="block?.children && block.children.length"></div>

As result if block.type === fielType.Block it renders a specific component then outside are rendered his children. But it should be rendered inside concrete component if children exist.

How to fix it?

My main scope to show components recursive, but display different components based on condition *ngIf="block.tag.

As solution:

I can add <app-document-form-node> inside templates of <app-adresat-list, <app-word-settings>, <app-parameters>, app-document-parameters but it invokes circula dependency components error.

Another assumption is to use <ng-template #children> reference and projection in each components:

<ng-container *ngIf="block.type === fielType.Block">
    <app-adresat-list *ngIf="block.tag === 'ADRESATS'" [list]="block?.children">
        <ng-container *ngTemplateOutlet="children; context: { block: block }"> </ng-container>
    </app-adresat-list>
    <app-word-settings *ngIf="block.tag === 'WORD_SETTINGS'" [element]="block">
        <ng-container *ngTemplateOutlet="children; context: { block: block }"> </ng-container>
    </app-word-settings>
    <app-parameters *ngIf="block.tag === 'PARAMETERS'" [element]="block">
        <ng-container *ngTemplateOutlet="children; context: { block: block }"> </ng-container>
    </app-parameters>
    <app-document-parameters *ngIf="block.tag === 'GENERICPARAMETERS'" [element]="block">
        <ng-container *ngTemplateOutlet="children; context: { block: block }"> </ng-container>
    </app-document-parameters>
</ng-container>

<!----->

<ng-container *ngIf="block.type === fielType.Field">
    <app-field [ismultisignator]="properties?.ismultisignator" [fieldDefinition]="block" (onSelected)="onFieldSelected($event)"></app-field>
</ng-container>

<!----->

<ng-container *ngIf="block.type === fielType.Table">
    <app-postaddress *ngIf="block.tag === 'TAG_ADDR'" [element]="block"></app-postaddress>
</ng-container>

<!--------------->

<ng-template #children let-block="block">
    <ng-container *ngIf="block?.children">
        <ng-container *ngFor="let child of block.children">
            <app-document-form-node [block]="child"></app-document-form-node>
        </ng-container>
    </ng-container>
</ng-template>

The code above works, but renders components in wrong sequence

Ali Bigdeli
  • 1,286
  • 3
  • 17
  • 35

1 Answers1

0

if you have children in all kinds of *ngIf="block.type === fielType.Block" you can simply just add <app-document-form-node [block]="block.children"></app-document-form-node> at the end of your first ng-container.

<ng-container *ngIf="block.type === fielType.Block">
    <app-adresat-list *ngIf="block.tag === 'ADRESATS'" [list]="block?.children"></app-adresat-list>
    <app-word-settings *ngIf="block.tag === 'WORD_SETTINGS'" [element]="block"></app-word-settings>
    <app-parameters *ngIf="block.tag === 'PARAMETERS'" [element]="block"></app-parameters>
    <app-document-parameters *ngIf="block.tag === 'GENERICPARAMETERS'" [element]="block"></app-document-parameters>
    <app-document-form-node [block]="block.children"></app-document-form-node>
</ng-container>
roya
  • 286
  • 1
  • 8
  • you are doing so! i said at the end of your `ng-container`. it means, keep your lines and append `app-document-form-node` to it! – roya Aug 14 '20 at 07:51
  • Could you extend your answer with that? It is not clear in the words –  Aug 14 '20 at 07:53
  • 1
    updated answer, if the result is not what you want, then the only way to understand your question is to prepare data model and result image otherwise it's not clear. – roya Aug 14 '20 at 08:04