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:
<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>
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 :)
A component is composed of two Files Ts and HTML mainly. Html is the view. but you can not have multiple templates, as binding will be issue and rendering can not be done. Instead, you can have multiple components inside one component, with each having different templates you need.
Note Although it's possible for a component to render multiple templates, we recommend using an if:true|false directive to render nested templates conditionally instead.
This template uses typical HTML elements like <h2> and <p> , and also includes Angular template-syntax elements, *ngFor , {{hero.name}} , (click) , [hero] , and <app-hero-detail> . The template-syntax elements tell Angular how to render the HTML to the screen, using program logic and data.
As far as I know it cannot be done using 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>
Then you need to inject the template to your component with @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; }
There is one last thing, our component uses 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(); } }
In recent version above can be done using *ngIf="somevar"
, while you can pass "somevar" value using @input
.
Example:
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With