Пользовательское имя тега для динамического компонента Angular

У меня есть простой компонент

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

И еще один, который создает экземпляр первого:

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

Шаблон AppComponent просто

<template #myContainer></template>

, поэтому вывод

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

Что я пытаюсь сделать, так это настроить шаблон MyComponent во время создания экземпляра и заменить его тег p тегом, имя которого должно быть tagName. Я знаю имя тега прямо перед созданием MyComponent при выполнении метода AppComponent.ngOnInit.

И еще одна задача, которую я пытаюсь решить, — это настройка имени тега-оболочки MyComponent. Замена <div my-component>... на <span my-component>..., где "span" - желаемое имя тега, которое также известно как AppComponent.ngOnInit.

Итак, можно ли программно обеспечить такую ​​​​настройку и получить следующее:

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

? tagName может быть любым разрешенным тегом HTML, а ngIf/Switch не подходит. Я создал демонстрацию для быстрого погружения: https://stackblitz.com/edit/angular-zngyoa


person dhilt    schedule 25.10.2018    source источник


Ответы (1)


Для задачи 1 используйте строковое регулярное выражение, которое заменит «p» тегом «span». Это должно быть сделано внутри метода жизненного цикла ngAfterViewInit.

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;
    }
  }
}
person Suresh Kumar Ariya    schedule 25.10.2018