条件に基づく1つのコンポーネントの複数のテンプレート
だからここに契約がある。非常によく書かれ、多くの場所で使用されているコンポーネントがあります。ここで、同じコンポーネントを使用する必要がありますが、条件に基づいて異なるテンプレートをレンダリングする必要があります。
私はたくさん試しました。
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が1回しか実行されないことです。そのため、isWizardがtrueの場合、divブロックが表示されていても、ng-contentは実行されません(上記のブロックで実行されたため)。
5)ngIfを使用する代わりにngSwitchも試しました-動作しませんでした
今私は必死です。助けてください :)
私の知る限り、_ng-content
_を使用してそれを行うことはできませんが、templates
(または_ng-templates
_ in Angular 4+)を使用してこれを達成できます。コンテンツをコンポーネントに直接渡すのではなく、次のように_<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();
}
}
_
おそらく、ここで作成した解決策を試すことができます 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
これは私の問題で動作し、これをお勧めします:)
上記の最近のバージョンでは、*ngIf="somevar"
を使用して実行できますが、@input
を使用して「somevar」値を渡すことができます。
例:
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() {
}
}
<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>