基于条件的一个组件多个模板 [英] One Component Multiple Templates based on Condition
问题描述
所以这就是交易.我有一个组件写得很好,并在很多地方使用.现在我需要使用相同的组件,但希望根据条件呈现不同的模板.
我尝试了很多.
1) 尝试使用多个组件装饰器 - 没有运气
2) 尝试了多层次的抽象,我最终创建了更多的组件 - 坏主意
3) 可以从字面上复制整个组件,只需更改选择器和模板 - 坏主意
4) 目前我正在尝试这个:
<ul class="nav" role="tablist"><ng-content select="tab-link"></ng-content><ng-content select="tab-content"></ng-content><div *ngIf="isWizard"><nav class="nav-panel sidenav"><ng-content select=".wizard-title"></ng-content><ul class="nav" role="tablist"><ng-content select="tab-link"></ng-content></nav><main class="settings-panel content-area"><ng-content select="tab-content"></ng-content></main>
我将 isWizard 属性设置为 true/false.现在的问题是,ng-content 只运行一次.所以当 isWizard 为 true 时,即使显示了 div 块,ng-content 也不会运行(因为它在上面的块中运行).
5) 而不是使用 ngIf 我也试过 ngSwitch - 没用
我现在很绝望.请帮忙:)
据我所知,使用 ng-content
无法实现,但您可以使用 templates
实现>(或 Angular 4+ 中的 ng-templates
).因此,与其将内容直接传递给您的组件,不如将其包装在 中,如下所示:
<template>Hello World!</template></my-component>
然后您需要使用 @ContentChild(TemplateRef)
将模板注入到您的组件中,并根据需要多次渲染.
@Component({选择器:我的组件",模板:`<div *ngIf="!isWizard">第一个:<template [ngTemplateRenderer]="template"></template>
<div *ngIf="isWizard">第二个:<template [ngTemplateRenderer]="template"></template>
`})导出类 MyComponent {@ContentChild(TemplateRef)私有模板:TemplateRef 最后一件事,我们的组件使用 So here's the deal. I have a component thats very well written and being used in a lot of places. Now I need to use the same component, but want a different template to be rendered, based upon a condition. I tried a lot. 1) Tried using multiple component decorators - no luck 2) Tried multiple level of abstractions, where I just ended up creating more components - bad idea 3) Can literally copy the whole component, and just change the selector and template - bad idea 4) Currently I was trying this: I set the isWizard property as true/false.
Now the problem is, ng-content runs only once. So when isWizard is true, even though the div block is displayed, ng-content doesn't run ( cause it ran in the above block ). 5) Instead of using ngIf I also tried ngSwitch - didn't work I'm desperate now. Please help :) As far as I know it cannot be done using Then you need to inject the template to your component with There is one last thing, our component uses
这篇关于基于条件的一个组件多个模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!ngTemplateRenderer
,这是一个简单的实用指令,用于呈现通过引用传递的模板.这是该指令的代码:@Directive({ selector: '[ngTemplateRenderer]'})导出类 TemplateRenderer 实现 OnInit, OnDestroy {@Input("ngTemplateRenderer")私有模板:TemplateRef
<div *ngIf="!isWizard">
<ul class="nav" role="tablist">
<ng-content select="tab-link"></ng-content>
</ul>
<ng-content select="tab-content"></ng-content>
</div>
<div *ngIf="isWizard">
<nav class="nav-panel sidenav">
<ng-content select=".wizard-title"></ng-content>
<ul class="nav" role="tablist">
<ng-content select="tab-link"></ng-content>
</ul>
</nav>
<main class="settings-panel content-area">
<ng-content select="tab-content"></ng-content>
</main>
</div>
ng-content
but you could achieve this using templates
(or ng-templates
in Angular 4+). So instead of passing content directly to your component, just wrap it in <template>
like that:<my-component [isWizard]="true">
<template>Hello World!</template>
</my-component>
@ContentChild(TemplateRef)
and render it as many times as you wish.@Component({
selector: "my-component",
template: `
<div *ngIf="!isWizard">
first: <template [ngTemplateRenderer]="template"></template>
</div>
<div *ngIf="isWizard">
second: <template [ngTemplateRenderer]="template"></template>
</div>`
})
export class MyComponent {
@ContentChild(TemplateRef)
private template: TemplateRef<any>;
@Input("isWizard")
private isWizard: boolean;
}
ngTemplateRenderer
which is a simple utility directive that renders templates passed by reference. Here's the code for that directive:@Directive({ selector: '[ngTemplateRenderer]'})
export class TemplateRenderer implements OnInit, OnDestroy {
@Input("ngTemplateRenderer")
private template: TemplateRef<any>;
private view: EmbeddedViewRef<any>;
constructor(private container: ViewContainerRef) {}
ngOnInit(): void {
this.view = this.container.createEmbeddedView(this.template);
}
ngOnDestroy(): void {
this.view.destroy();
}
}