dhilt
dhilt

Reputation: 20744

Custom Tag Name for Angular dynamic Component

I have a simple component

@Component({
  selector: '[my-component]',
  template: `<i>1</i><p>content</p><b>2</b>`
})
export class MyComponent {
  public tagName: string;
}

And another one that instantiates the first:

export class AppComponent implements OnInit {
 @ViewChild("myContainer", { read: ViewContainerRef }) container;

  constructor(
      private viewContainer: ViewContainerRef,
      private resolver: ComponentFactoryResolver) {
  }

  ngOnInit() {
    this.container.clear();
    const compFactory = this.resolver.resolveComponentFactory(MyComponent);
    const componentRef = this.container.createComponent(compFactory);
    componentRef.instance.tagName = 'span';
  }
}

The template of the AppComponent is just

<template #myContainer></template>

, so the output is

<div my-component><i>1</i><p>content</p><b>2</b></div>

What I'm trying to do is to customise MyComponent template during instantiation and replace it's p tag with a tag which name should be tagName. I know the name of the tag right before MyComponent creating when AppComponent.ngOnInit method is being executed.

And another task I'm trying to solve is MyComponent wrapper tag name customisation. Replacing <div my-component>... with <span my-component>... where "span" is desired tag name which is also known at AppComponent.ngOnInit.

So is it possible to provide such a customisation programmatically and get following:

<span my-component><i>1</i><span>content</span><b>2</b></span>

? tagName could be any allowed HTML tag, and ngIf/Switch is not an option. I have created demo for quick dive: https://stackblitz.com/edit/angular-zngyoa

Upvotes: 2

Views: 1108

Answers (1)

Suresh Kumar Ariya
Suresh Kumar Ariya

Reputation: 9764

For Problem1, using string regex which will replace 'p' with 'span' tag. It should be done inside ngAfterViewInit life cycle method.

import { Component, OnInit, AfterViewInit, ElementRef } from '@angular/core';

@Component({
  selector: '[my-component]',
  template: `<i>1</i><p>content</p><b>2</b>`
})
export class MyComponent implements AfterViewInit, OnInit{
  public tagName: string;

  constructor(private elementref: ElementRef){}

  ngOnInit(){}

  ngAfterViewInit(){
    if(this.tagName && this.elementref){
      let htmlcontent = this.elementref.nativeElement.innerHTML;
      htmlcontent = htmlcontent.replace(/p/g, 'span');
      this.elementref.nativeElement.innerHTML = htmlcontent;
    }
  }
}

Upvotes: 1

Related Questions