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
In angular 7.x I used angular-elements for this.
Install @angular-elements npm i @angular/elements -s
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".
@Component({
selector: 'app-root',
template: ' '
})
export class AppComponent {
constructor(
dynamicComponents: DynamicComponentsService,
) {
dynamicComponents.register();
}
}
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.