如何递归显示不同的组件?

How to display different components recursive?

我有一个 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>

问题出在 <ng-container *ngIf="block.type === fielType.Block"></ng-container>.

部分

发生这种情况时,所有子组件都应放在组件 <app-adresat-list<app-word-settings><app-parameters>app-document-parameters 中,以防 blockchildren.

现在可以了,但是毕竟上面提到的组件:

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

结果 if block.type === fielType.Block 它渲染了一个特定的组件,然后在外面渲染了他的子组件。但如果子组件存在,它应该在具体组件中呈现。

如何解决?

我的主要范围是递归显示组件,但根据条件显示不同的组件*ngIf="block.tag

作为解决方案:

我可以在 <app-adresat-list<app-word-settings><app-parameters>app-document-parameters 的模板中添加 <app-document-form-node>,但它会调用循环依赖组件错误。

另一个假设是在每个组件中使用<ng-template #children>参考和投影:

<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>

上面的代码有效,但以错误的顺序呈现组件

如果您在各种 *ngIf="block.type === fielType.Block" 中有 children,您只需在第一个 ng-container.

的末尾添加 <app-document-form-node [block]="block.children"></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>
    <app-document-form-node [block]="block.children"></app-document-form-node>
</ng-container>