Один компонент Несколько шаблонов на основе условия

Итак, вот сделка. У меня есть компонент, который очень хорошо написан и используется во многих местах. Теперь мне нужно использовать один и тот же компонент, но вам нужен другой шаблон для визуализации, основанный на условии.

Я много пробовал.

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 является истинным, даже если отображается div-блок, ng-контент не запускается (запустите его в указанном выше блоке).

5) Вместо использования ngIf я также попробовал ngSwitch - не работал

Теперь я в отчаянии. Пожалуйста, помогите:)

Ответ 1

Насколько я знаю, это невозможно сделать с помощью ng-content, но вы можете достичь этого, используя templates (или ng-templates в 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(); 
    }
}

Ответ 2

В последней версии выше можно сделать, используя * ngIf = "somevar", в то время как вы можете передать значение "somevar" с помощью @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() {
		
	}
}
<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>