This is strange. Whenever I render my custom element, the body (innerHTML) of the element gets appended at the end.
This is my homepage - see 'childbody' is in the body of the s-child
element:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: '<s-child>childbody</s-child>'
})
export class AppComponent {
title = 'test-app';
}
This is my s-child
element - Note that I'm not rendering <ng-content>
anywhere:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-child',
template: '<p>child works!</p>'
})
export class ChildComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}
This is the output when I run this app - Note that 'childbody' is appended at the end, despite it not being 'asked to render anywhere' (i.e the weird part) -
This is my app-module where I declare the custom element - this is just FYI / additional context:
import { BrowserModule } from '@angular/platform-browser';
import { CUSTOM_ELEMENTS_SCHEMA, Injector, NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ChildComponent } from './test/child/child.component';
import {createCustomElement} from '@angular/elements';
@NgModule({
declarations: [
AppComponent,
ChildComponent
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent],
entryComponents: [ChildComponent],
schemas: [
CUSTOM_ELEMENTS_SCHEMA
]
})
export class AppModule {
constructor(injector: Injector) {
const child = createCustomElement(ChildComponent, {injector: injector});
customElements.define('s-child', child);
}
}
I wanted to provide a Stackblitz, but that's behaving weirdly with custom elements, apologies for that. I'm using Angular 10.2.4.
Ok, after 6.5 hours of head-banging, I figured out a solution -
When the element is used directly within a component - The selector of the corresponding element should be used (not the element tag).
When an element is dynamically inserted, the tag for custom element can be used, possibly with a sanitizer, e.g. -
constructor(private sanitizer: DomSanitizer) {
}
ngOnInit() {
this.sanitizedData = this.sanitizer.bypassSecurityTrustHtml('<s-child>adsf</s-child>')
}