ng-content внутри ng-template всегда создает контент, даже если шаблон не отображается

Я столкнулся со странной ошибкой с ng-content, завернутым в ng-template.

Допустим, у меня есть компонент inner-component, который я отображаю в outer-component:

<ng-container *ngIf="condition" [ngTemplateOutlet]="test"></ng-container>
<ng-template #test>
    <inner-component></inner-component>
</ng-template>

Если condition=false, то, как и ожидалось, мой inner-component никогда не создается Angular (при отладке никогда не вызывается ngOnInit()).

Теперь, если вместо этого у меня есть внешний компонент:

<ng-container *ngIf="condition" [ngTemplateOutlet]="test"></ng-container>
<ng-template #test>
    <ng-content></ng-content>
</ng-template>

и, все еще с condition=false, я пишу:

<outer-component>
    <inner-component></inner-component>
</outer-component>

Затем, к моему удивлению, создается inner-component, даже если он никогда не визуализируется. Это проблема для меня, потому что внутренний компонент (сторонний компонент, который я не могу изменить) действительно необходимо создавать при его отображении в приложении.

Можете ли вы придумать обходной путь, который я мог бы использовать для внешнего компонента, чтобы избежать создания ng-контента (очевидно, все еще используя трансклюзию - первое решение не вариант).


person Eric Leibenguth    schedule 09.09.2020    source источник
comment
возможно, вы написали в .ts условие = ложь (строка) - ну, обычно это происходит, когда данные получены от службы и являются строкой - или у вас есть ссылочная переменная шаблона, называемая условием   -  person Eliseo    schedule 09.09.2020
comment
О, я понимаю, что ты сейчас делаешь! Вы не хотите, чтобы компонент inner был инициализирован снаружи внешнего, а внутри шаблона outer-component с использованием условного выражения вокруг ng-content.   -  person hyperdrive    schedule 09.09.2020
comment
Да, после долгих головоломок я думаю, что на самом деле это та же проблема, что описана здесь: stackoverflow.com/questions/44929726/, за исключением того, что я не могу использовать предложенное решение...   -  person Eric Leibenguth    schedule 09.09.2020


Ответы (1)


Вы можете переместить шаблон в родительский компонент.

<app-outer>
    <ng-template #test>
        <app-inner></app-inner>
    </ng-template>
</app-outer>

И в вашем externalComponent получите дочернюю ссылку на шаблон

@ContentChild('test') testTemplate: TemplateRef<ElementRef>;

Внешний HTML

<ng-container *ngIf="condition" [ngTemplateOutlet]="testTemplate"></ng-container>

Stackblitz

person hyperdrive    schedule 09.09.2020
comment
Хм, нет, мой внутренний компонент находится в нужном месте, в шаблоне test. Этот шаблон test должен отображаться в первом контейнере ng, если условие true - person Eric Leibenguth; 09.09.2020
comment
Фейспалм. Обновите ответ, я думаю, поэтому. - person hyperdrive; 09.09.2020
comment
Ваш ответ правильный, но я бы хотел, чтобы был способ сохранить текущий API для моего внешнего компонента (то есть избежать того, чтобы ng-template обертывал внутренний компонент) - person Eric Leibenguth; 09.09.2020
comment
@EricLeibenguth Пара вещей, которые вы также можете рассмотреть, это динамическая загрузка компонентов или создание пользовательских структурных директив. Я боролся с этой же проблемой раньше. - person hyperdrive; 09.09.2020