所以这是交易。我有一个非常好的组件,并在很多地方使用。现在我需要使用相同的组件,但希望根据条件呈现不同的模板。
我尝试了很多。
1)尝试使用多个组件装饰器 - 没有运气
2)尝试了多层次的抽象,我最终创造了更多的组件 - 糟糕的主意
3)可以逐字复制整个组件,只需更改选择器和模板 - 坏主意
4)目前我正在尝试这个:
<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>
我将isWizard属性设置为true / false。 现在的问题是,ng-content只运行一次。因此,当isWizard为true时,即使显示div块,ng-content也不会运行(导致它在上面的块中运行)。
5)而不是使用ngIf我也试过ngSwitch - 没有工作
我现在很绝望。请帮助:)
答案 0 :(得分:3)
据我所知,使用ng-content
无法完成此操作,但您可以使用templates
(或Angular 4+中的ng-templates
)来实现此目的。因此,不要将内容直接传递给您的组件,而是将其包装在<template>
中,如下所示:
<my-component [isWizard]="true">
<template>Hello World!</template>
</my-component>
然后,您需要使用@ContentChild(TemplateRef)
将模板注入到组件中,并根据需要多次渲染。
@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
这是一个简单的实用程序指令,它通过引用呈现模板。这是该指令的代码:
@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();
}
}
答案 1 :(得分:0)
在上面的最新版本可以使用*ngIf="somevar"
完成,而你可以通过&#34; somevar&#34;价值使用@input
。
示例:
import { Component, OnInit, Input, Output, EventEmitter} from '@angular/core';
import {SearchPipe} from './../filters/search.pipe';
@Component({
selector: 'itra-filter',
templateUrl: 'filter.component.html',
styleUrls: ['filter.component.scss'],
inputs:['IsCheckboxEnabled','IsRadioboxEnabled'],
outputs: ['itemClicked']
})
export class ItraFilterComponent {
// Default Value
public IsCheckboxEnabled:boolean = false;
public IsRadioboxEnabled:boolean = false;
constructor() {
}
ngOnInit() {
}
}
&#13;
<span class="checkbox-control" *ngIf="IsCheckboxEnabled">
<i class="icon icon_Check-box_filled" *ngIf="y.checked"></i>
<i class="icon icon_Check-box" *ngIf="!y.checked"> </i>
</span>
<span class="radiobox-control" *ngIf="IsRadioboxEnabled">
<i class="icon icon_Radio-button-filled" *ngIf="y.checked"></i>
<i class="icon icon_Radio-button" *ngIf="!y.checked"></i>
</span>
&#13;
答案 2 :(得分:0)
也许,我们可以尝试这里提出的解决方案,angular 2 include html templates。
我对这个解决方案非常满意,因为我处于相同的情况,比如根据某些值切换模板,最终不会用大量的行来搞乱代码。
我只是简单地描述了我项目的结构,
Component Structure
====================
Comp A
-> Comp a1
-> Comp a2
-> Comp a3
-> Comp a-consolidated*(declaring all needed component's selectors)
Comp B
Comp C
Comp D
这适用于我的问题,我建议:)