Html ngIf为false时生成Angular4 ng内容
我对新的Html ngIf为false时生成Angular4 ng内容,html,angular,typescript,angular2-template,Html,Angular,Typescript,Angular2 Template,我对新的ng内容transclusion有问题 假设我有一个组件mycomponent,它在ngOnInit()函数中执行一些重载操作(目前,它只是一个console.log()) 我有一个包装器,它通过转换显示内容(my wrapper.component.html) 我总是看到console.log()输出。我猜,mycomponent被构建,然后被存储起来,直到*ngIf变成true在mywrapper中 其目的是构建一个通用的“列表项+细节”组件。假设我有一个N个概览元素的列表(mywr
ng内容transclusion有问题
假设我有一个组件mycomponent
,它在ngOnInit()
函数中执行一些重载操作(目前,它只是一个console.log()
)
我有一个包装器,它通过转换显示内容(my wrapper.component.html
)
我总是看到console.log()
输出。我猜,mycomponent
被构建,然后被存储起来,直到*ngIf
变成true
在mywrapper
中
其目的是构建一个通用的“列表项+细节”组件。假设我有一个N个概览元素的列表(mywrapper
),这些元素在*ngFor
循环中呈现。这些元素中的每一个都有自己的细节组件(mycomponent
),一旦我决定向特定项目显示更多信息,这些组件就应该加载自己的数据
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>
点击查看更多信息
有没有办法告诉Angular,在需要添加到页面之前忽略转置的内容?类似于AngularJS中的情况。通过这样做:
<my-wrapper *ngIf="false">
<my-component></my-component>
</my-wrapper>
<ng-container *ngIf="false">
<ng-content></ng-content>
</ng-container>
您在组件内部,您只是在限制在模板中渲染的内容,但您已经实例化了组件,因此,您通过了ngOnInit
,并完成了控制台日志
如果要限制某些内容(使用选择器的组件调用或ng content
或甚至div
),直到有一些数据可用,可以执行以下操作:
datasLoaded: Promise<boolean>;
this.getData().subscribe(
(data) => {
this.datasLoaded = Promise.resolve(true); // Setting the Promise as resolved after I have the needed data
}
);
数据加载:承诺;
这是.getData().subscribe(
(数据)=>{
this.datasload=Promise.resolve(true);//在获得所需数据后将承诺设置为已解析
}
);
在模板中:
<ng-container *ngIf="datasLoaded | async">
// stuff here
</ng-container>
//这里的东西
或:
//没有测试这个,但是应该遵循相同的逻辑。如果没有,则包装它并将ngIf添加到包装器中
根据@nsinreal的评论,我找到了答案。我觉得它有点深奥,所以我试着把它贴在这里:
答案是使用ng template
和*ngTemplateOutlet
在mywrapper
组件中,按如下方式设置模板(mywrapper.component.html
):
现在,您可以像这样使用包装器:
<my-wrapper>
<ng-template>
<my-component></my-component>
</ng-template>
</my-wrapper>
我不知道为什么它需要如此复杂的“变通方法”,而在AngularJS中这样做很容易。这是因为Ng内容发生在构建时,当您传递内容时,它实际上没有被删除或用ngIf指令重新创建。它只被移动,组件被实例化。我最近也遇到了这个问题,但解决方案与当前接受的不同
解决方案(TL;DR)
(解决方案是针对AngularDart;我认为它在角度上是相似的)
使用结构指令;教程链接如下
而不是:
您的使用变成:
这是以下内容的简写(在AngularDart中;我认为Angular使用
)
MyWrapper
指令逻辑与NgIf
类似,只是它有自己的逻辑来计算条件。以下两个教程都解释了如何创建类似NgIf的指令,以及如何使用特殊的microsyntax(例如*myWrapper=“myInput:expression”
)将自己的输入传递给用户。请注意,microsyntax不支持输出(@Output
),但您可以使用作为函数的输入来模拟输出
注意事项:由于这只是一个指令,它不应该做比在适当的时间实例化模板引用和指定一些DI提供程序更复杂的事情。例如,我将避免尝试在指令中应用样式或实例化复杂的组件树。如果我想创建一个列表组件,我可能会采用另一个答案中描述的@ContentChild(TemplateRef)
方法;您将失去创建
的星号速记,但您将获得组件的全部功能
我的问题
我的团队拥有一个属于大型web应用程序的应用程序,其他团队拥有其他应用程序。我们的组件假定它们可以注入一个MyAppConfiguration
对象,但是这个对象只有在加载异步请求后才能被注入。在我们的应用程序中,这不是一个问题:我们有一个“shell”组件,它将所有内容隐藏在ngIf
后面,直到加载配置
问题是当其他团队想要引用我们的组件时。我们不希望他们每次都重复“等待配置加载”逻辑,因此我尝试创建一个包装器组件,可以像这样使用:
包装器注入服务对象并将其内容隐藏在ngIf
后面,直到服务表示已加载配置
与问题海报一样,我发现ng content
方法没有按预期工作:虽然内容正确地隐藏在DOM中,但Angular仍然实例化了导致依赖注入失败的组件
我决定的解决方案是将包装器组件重写为结构指令。我建议不要在包装器上添加条件,而是将条件添加到子组件以停止执行。我认为这在我的情况下不起作用。这样做的目的是:我有一个概览数据列表,在*ngFor
-循环(mywrapper
)中呈现。对于每个概述项目,我都有第二个“细节”组件(my component
),即
datasLoaded: Promise<boolean>;
this.getData().subscribe(
(data) => {
this.datasLoaded = Promise.resolve(true); // Setting the Promise as resolved after I have the needed data
}
);
<ng-container *ngIf="datasLoaded | async">
// stuff here
</ng-container>
<my-component *ngIf="datasLoaded | async">
// Didn't test this one, but should follow the same logic. If it doesn't, wrap it and add the ngIf to the wrapper
</my-component>
<div (click)="toggleDetail()">Click for more</div>
<div *ngIf="showDetail" [hidden]="!isInitialized">
<ng-container *ngTemplateOutlet="detailRef"></ng-container>
</div>
import { ContentChild, TemplateRef } from '@angular/core';
@Component({ ... })
export class MyWrapperComponent {
@ContentChild(TemplateRef) detailRef;
...
}
<my-wrapper>
<ng-template>
<my-component></my-component>
</ng-template>
</my-wrapper>