ngIf为false时会构建Angular4 ng-content [英] Angular4 ng-content gets built when ngIf is false
问题描述
我对新的ng-content
包含项有疑问.
I have a problem with the new ng-content
transclusion.
比方说,我有一个组件my-component
,它的ngOnInit()
函数在负载时进行了一些繁重的操作(目前仅是console.log()
).
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()
).
我有一个包装器,该包装器通过包含(my-wrapper.component.html
)来显示内容.
I have a wrapper, that displays the content via transclusion (my-wrapper.component.html
).
<ng-content></ng-content>
如果我这样设置环境,则log语句不会显示:
If I set the surroundings up like this, the log statement doesn't show:
<my-wrapper *ngIf="false">
<my-component></my-component>
</my-wrapper>
我认为my-wrapper
组件未构建,因此其内容将被忽略.
I assume, the my-wrapper
component does not get built, so the content is ignored.
但是,如果我尝试将逻辑移入这样的my-wrapper
组件(my-wrapper.component.html
):
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>
我总是看到console.log()
输出.我猜想,my-component
会被构建,然后存储起来,直到*ngIf
成为my-wrapper
内部的true
.
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
.
目的是构建一个通用的列表项+详细信息"组件.假设我有N个概述元素(my-wrapper
)的列表,这些元素在*ngFor
循环中呈现.一旦我决定向特定项目显示更多信息,这些元素中的每个元素都有其自己的详细信息组件(my-component
),该组件应该加载其自己的数据.
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:
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:
my-wrapper.component.html:
<div (click)="toggleDetail()">Click for more</div>
<div *ngIf="showDetail">
<ng-content></ng-content>
</div>
有没有办法告诉Angular,在需要将其添加到页面之前,忽略已包含的内容?类似于AngularJS中的情况.
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.
推荐答案
基于@nsinreal的评论,我找到了答案.我觉得它有些深奥,所以我尝试将其发布在这里:
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:
答案是与ng-template
和*ngTemplateOutlet
一起使用.
在my-wrapper
组件中,像这样(my-wrapper.component.html
)设置模板:
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>
请注意,[hidden]
并不是真正必要的,它会隐藏子级的原始"模板,直到确定完成加载为止.只要确保不要将它放在*ngIf
中,否则*ngTemplateOutlet
就永远不会触发,导致什么也没有发生.
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.
要设置detailRef
,请将其放在组件代码(my-wrapper.component.ts
)中:
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>
我不确定,为什么以前在AngularJS中很容易做到这一点,为什么它需要这么复杂的变通办法".
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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!