Is there anyway to change this:
<div>Some text here</div>
To:
<tr>Some text here</tr>
Change the tag DIV tag to TR tag dynamically? Basically Replace the Tags?
Is there anyway to change this:
<div>Some text here</div>
To:
<tr>Some text here</tr>
Change the tag DIV tag to TR tag dynamically? Basically Replace the Tags?
you could create custom structure directive to do this.
replace-tag.directive.ts
import { Directive, Input, TemplateRef, ViewContainerRef, ElementRef, AfterViewChecked } from '@angular/core';
@Directive({
selector: '[replaceTag]'
})
export class ReplaceTagDirective implements AfterViewChecked {
constructor(
private templateRef: TemplateRef<any>,
private vcf: ViewContainerRef
) { }
private _tag: string;
private _needUpdate: boolean = false;
@Input('replaceTag')
set tag(t: string): void {
this._tag = t;
this._needUpdate = true;
this.vcf.clear();
let template = this.templateRef.elementRef.nativeElement.nextElementSibling;
if (template) {
this.templateRef.elementRef.nativeElement.parentNode.removeChild(template);
}
this.vcf.createEmbeddedView(this.templateRef);
}
ngAfterViewChecked() {
if (this._needUpdate) {
this._updateTemplate();
this._needUpdate = false;
}
}
private _updateTemplate() {
let template = this.templateRef.elementRef.nativeElement.nextElementSibling;
if (template) {
let r = document.createElement(this._tag);
r.innerHTML = template.innerHTML;
this.templateRef.elementRef.nativeElement.parentNode.replaceChild(r, template);
}
}
}
app.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root',
template: `
App
<span *replaceTag="tag">
<strong>content {{ tag }} </strong>
<em>{{ message }}</em>
</span>
`
})
export class AppComponent implements OnInit {
tag: string = 'div';
timeOut: number = 2;
get message(): string {
return this.timeOut? `<- this tag will change after ${this.timeOut} seconds.` : 'done';
}
ngOnInit() {
setTimeout(() => {
this.tag = 'h2';
this.timeOut = 4;
}, 2000);
setTimeout(() => {
this.tag = 'sub';
this.timeOut = 0;
}, 4000);
}
}
We can use Grochni's approach to provide us a dynamic html element container using ng-template
.
<ng-container [ngTemplateOutlet]="showTr ? tr : div" [ngTemplateOutletContext]="{ $implicit: content }">
</ng-container>
<ng-template #content>
Some text here
</ng-template>
<ng-template #tr let-content>
<tr><ng-container [ngTemplateOutlet]="content"></ng-container></tr>
</ng-template>
<ng-template #div let-content>
<div><ng-container [ngTemplateOutlet]="content"></ng-container></div>
</ng-template>
Here is another way to avoid duplication. I needed to use a different tag depending on some condition:
Create template which both tags will use:
<ng-template #tagTemplate>
<h1>Hello and Hi</h1>
<p>Bye</p>
</ng-template>
Define both tags and use ngIf
. The content of the tags will be the template created above.
<div class="post-widget" *ngIf="data">
<ng-container *ngTemplateOutlet="tagTemplate;"></ng-container>
</div>
<ion-content class="post-widget" *ngIf="!data">
<ng-container *ngTemplateOutlet="tagTemplate;"></ng-container>
</ion-content>
you can use *ngIf on each one of them
<div *ngIf="someFunction()">Some text here</div>
<tr *ngIf="someFunction()">Some text here</tr>
Try this, where you manage (bool) show_div in your controller.
//Js
$scope.show_div = true;
<!--Html-->
<div ng-if="show_div">Some text here</div>
<tr ng-if="!show_div">Some text here</tr>