How can I use/create dynamic template to compile dynamic Component with Angular 2.0?

后端 未结 15 1943
忘掉有多难
忘掉有多难 2020-11-21 05:14

I want to dynamically create a template. This should be used to build a ComponentType at runtime and place (even replace) it somewhere inside of the ho

15条回答
  •  我寻月下人不归
    2020-11-21 05:58

    In angular 7.x I used angular-elements for this.

    1. Install @angular-elements npm i @angular/elements -s

    2. Create accessory service.

    import { Injectable, Injector } from '@angular/core';
    import { createCustomElement } from '@angular/elements';
    import { IStringAnyMap } from 'src/app/core/models';
    import { AppUserIconComponent } from 'src/app/shared';
    
    const COMPONENTS = {
      'user-icon': AppUserIconComponent
    };
    
    @Injectable({
      providedIn: 'root'
    })
    export class DynamicComponentsService {
      constructor(private injector: Injector) {
    
      }
    
      public register(): void {
        Object.entries(COMPONENTS).forEach(([key, component]: [string, any]) => {
          const CustomElement = createCustomElement(component, { injector: this.injector });
          customElements.define(key, CustomElement);
        });
      }
    
      public create(tagName: string, data: IStringAnyMap = {}): HTMLElement {
        const customEl = document.createElement(tagName);
    
        Object.entries(data).forEach(([key, value]: [string, any]) => {
          customEl[key] = value;
        });
    
        return customEl;
      }
    }
    
    

    Note that you custom element tag must be different with angular component selector. in AppUserIconComponent:

    ...
    selector: app-user-icon
    ...
    

    and in this case custom tag name I used "user-icon".

    1. Then you must call register in AppComponent:
    @Component({
      selector: 'app-root',
      template: ''
    })
    export class AppComponent {
      constructor(   
        dynamicComponents: DynamicComponentsService,
      ) {
        dynamicComponents.register();
      }
    
    }
    
    1. And now in any place of your code you can use it like this:
    dynamicComponents.create('user-icon', {user:{...}});
    

    or like this:

    const html = `
    `; this.content = this.domSanitizer.bypassSecurityTrustHtml(html);

    (in template):

    Note that in second case you must pass objects with JSON.stringify and after that parse it again. I can't find better solution.

提交回复
热议问题