本文介绍了当 ngIf 为 false 时构建 Angular4 ng-content的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对新的 ng-content 转置有疑问.

假设我有一个 my-component 组件,它在它的 ngOnInit() 函数中做了一些负载操作(现在,只是一个 控制台.log()).

我有一个包装器,它通过嵌入显示内容 (my-wrapper.component.html).

如果我这样设置环境,日志语句不会显示:

<我的组件></我的组件></my-wrapper>

我假设 my-wrapper 组件没有被构建,所以内容被忽略.

但是,如果我尝试将逻辑移动到 my-wrapper 组件中,如下所示 (my-wrapper.component.html):

<ng-content></ng-content></ng-容器>

我总是看到 console.log() 输出.我猜, my-component 被构建然后存储起来,直到 *ngIfmy-wrapper 变成 true>.

目的是构建一个通用的列表项+详细信息"组件.假设我有一个包含 N 个概览元素 (my-wrapper) 的列表,这些元素在 *ngFor 循环中呈现.这些元素中的每一个都有自己的细节组件 (my-component),一旦我决定向特定项目显示更多信息,该组件就会加载自己的数据.

overview.html:

<我的包装器><my-component id="item.id"></my-component></my-wrapper></ng-容器>

my-wrapper.component.html:

<div (click)="toggleDetail()">点击查看更多</div><div *ngIf="showDetail"><ng-content></ng-content>

有没有办法告诉 Angular,忽略嵌入的内容,直到需要添加到页面?类似于 AngularJS 中的情况.

解决方案

根据@nsinreal 的评论,我找到了答案.我觉得它有点深奥,所以我想把它贴在这里:

答案是使用 ng-template*ngTemplateOutlet.

my-wrapper 组件中,像这样设置模板 (my-wrapper.component.html):

<div (click)="toggleDetail()">点击查看更多</div><div *ngIf="showDetail" [hidden]="!isInitialized"><ng-container *ngTemplateOutlet="detailRef"></ng-container>

请注意,[hidden] 并不是真正必要的,它会隐藏子项的原始"模板,直到它决定加载完毕.请确保不要将它放在 *ngIf 中,否则 *ngTemplateOutlet 将永远不会被触发,导致什么也不会发生.

要设置detailRef,把它放在组件代码中(my-wrapper.component.ts):

import { ContentChild, TemplateRef } from '@angular/core';@成分({ ... })导出类 MyWrapperComponent {@ContentChild(TemplateRef) detailRef;...}

现在,您可以像这样使用包装器:

<ng-模板><我的组件></我的组件></ng-模板></my-wrapper>

我不知道为什么它需要如此复杂的解决方法",而过去在 AngularJS 中这样做很容易.

I have a problem with the new ng-content transclusion.

Let's say I have a component my-component that, in its ngOnInit() function does some heavy operation on load (for now, just a console.log()).

I have a wrapper, that displays the content via transclusion (my-wrapper.component.html).

<ng-content></ng-content>

If I set the surroundings up like this, the log statement doesn't show:

<my-wrapper *ngIf="false">
    <my-component></my-component>
</my-wrapper>

I assume, the my-wrapper component does not get built, so the content is ignored.

But if I try to move the logic into the my-wrapper component like this (my-wrapper.component.html):

<ng-container *ngIf="false">
    <ng-content></ng-content>
</ng-container>

I always see the console.log() output. I guess, the my-component gets built and then stored away until the *ngIf becomes true inside my-wrapper.

The intention was to build a generic "list-item + detail" component. Say I have a list of N overview-elements (my-wrapper), that get rendered in a *ngFor loop. Every of those elements has its own detail component (my-component) that is supposed to load its own data, once I decide to show more infos to a specific item.

overview.html:

<ng-container *ngFor="let item of items">
    <my-wrapper>
        <my-component id="item.id"></my-component>
    </my-wrapper>
</ng-container>

my-wrapper.component.html:

<div (click)="toggleDetail()">Click for more</div>
<div *ngIf="showDetail">
    <ng-content></ng-content>
</div>

Is there a way to tell Angular, to ignore the transcluded content until it is necessary to be added to the page? Analogously to how it was in AngularJS.

解决方案

Based on the comment of @nsinreal I found an answer. I find it to be a bit abstruse, so I'm trying to post it here:

The answer is to work with ng-template and *ngTemplateOutlet.

In the my-wrapper component, set up the template like this (my-wrapper.component.html):

<div (click)="toggleDetail()">Click for more</div>
<div *ngIf="showDetail" [hidden]="!isInitialized">
    <ng-container *ngTemplateOutlet="detailRef"></ng-container>
</div>

Note, that the [hidden] there is not really necessary, it hides the "raw" template of the child until it decides it is done loading. Just make sure, not to put it in a *ngIf, otherwise the *ngTemplateOutlet will never get triggered, leading to nothing happening at all.

To set the detailRef, put this in the component code (my-wrapper.component.ts):

import { ContentChild, TemplateRef } from '@angular/core';

@Component({ ... })
export class MyWrapperComponent {
    @ContentChild(TemplateRef) detailRef;

    ...
}

Now, you can use the wrapper like this:

<my-wrapper>
    <ng-template>
        <my-component></my-component>
    </ng-template>
</my-wrapper>

I am not sure, why it needs such complicated "workarounds", when it used to be so easy to do this in AngularJS.

这篇关于当 ngIf 为 false 时构建 Angular4 ng-content的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 01:35