webentwicklung-frage-antwort-db.com.de

Eine Komponente Mehrere Vorlagen basierend auf Bedingung

Also hier ist der Deal. Ich habe eine Komponente, die sehr gut geschrieben ist und an vielen Orten verwendet wird. Jetzt muss ich dieselbe Komponente verwenden, möchte jedoch basierend auf einer Bedingung eine andere Vorlage gerendert werden. 

Ich habe viel versucht. 

1) Mit mehreren Komponentendekorateuren versucht - kein Glück

2) Ich habe mehrere Abstraktionsebenen ausprobiert, bei denen ich am Ende mehr Komponenten erstellt habe - eine schlechte Idee

3) Kann die gesamte Komponente buchstäblich kopieren und nur die Auswahl und die Vorlage ändern - schlechte Idee

4) Momentan versuchte ich das:

<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>

Ich setze die isWizard -Eigenschaft auf true/false . Nun ist das Problem, dass ng-content nur einmal ausgeführt wird. Wenn isWizard also true ist, wird ng-content nicht ausgeführt, obwohl der div-Block angezeigt wird (weil er im obigen Block ausgeführt wurde).

5) Anstelle von ngIf habe ich auch ngSwitch ausprobiert - funktionierte nicht

Ich bin jetzt verzweifelt. Bitte helfen :)

13
Varun Joshi

Soweit ich weiß, ist dies nicht mit ng-content möglich, aber Sie können dies mit templates (oder ng-templates in Angular 4+) erreichen. Anstatt den Inhalt direkt an Ihre Komponente zu übergeben, packen Sie ihn einfach in <template> so ein:

<my-component [isWizard]="true">
    <template>Hello World!</template>
</my-component>

Dann müssen Sie die Vorlage mit @ContentChild(TemplateRef) in Ihre Komponente einfügen und beliebig oft rendern.

@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;
}

Eine letzte Sache, unsere Komponente verwendet ngTemplateRenderer, eine einfache Utility-Anweisung, die als Referenz übergebene Vorlagen darstellt. Hier ist der Code für diese Direktive:

@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(); 
    }
}
3
Slawomir Dadas

Vielleicht können wir die hier gemachte Lösung ausprobieren: angle 2 include HTML-Vorlagen .

Ich bin mit dieser Lösung ziemlich zufrieden, da ich mich in der gleichen Situation befand wie das Wechseln von Templates basierend auf bestimmten Werten und letztendlich, um den Code nicht mit einer großen Anzahl von Zeilen durcheinander zu bringen.

Ich beschreibe nur die Struktur meines Projekts zur Klarstellung,

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 

Das funktioniert bei meinem Problem und ich empfehle das :)

In der letzten Version können Sie *ngIf="somevar" verwenden, während Sie mit @input den Wert "somevar" übergeben können.

Beispiel:

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>

0
Sahil Gupta