Usually the HTML tag of an Angular component is it's selector. But it's possible to create a component with a different host HTML element. If you want to create a component statically (in the HTML template), you can use an attribute selector defined in the @Component
decorator. Or if you want to create a component dynamically via Angular API (e.g. createComponent()
or ComponentFactory.create()
), you can pass a custom host DOM element as a parameter.
Creating a component statically
TLDR: See the stackblitz: creating a component statically with a custom HTML tag.
Define a component with an attribute selector instead of element selector:
@Component({
// Note the brakets around `my-component`, denoting an "attribute selector" instead of "element selector"
selector: '[my-component]'
/* ... */
})
export class MyComponent { /* ... */ }
Then create this component with a custom HTML tag, by referencing it as an attribute:
<article my-component></article>
Creating a component dynamically
TLDR: See the stackblitz: creating a component dynamically with a custom HTML tag .
Here, the selector doesn't matter. Can be even normal:
@Component({
selector: 'my-component'
/* ... */
})
export class MyComponent { /* ... */ }
Then pass an existing DOM element as a host to the function for creating the component dynamically (e.g. to createComponent()
from @angular/core
):
import {
createComponent,
/* ... */
} from '@angular/core';
@Component(/*...*/)
export class ParentComponent {
constructor(
protected injector: Injector,
protected environmentInjector: EnvironmentInjector,
protected viewContainerRef: ViewContainerRef
) {}
ngOnInit() {
// create a fresh element, detached from DOM
const hostElement = document.createElement('article');
// create MyComponent, passing the `hostElement` param
const component = createComponent(MyComponent, {
hostElement, // <-----------------------------------
environmentInjector: this.environmentInjector,
elementInjector: this.injector,
});
// insert this component into the `ViewContainerRef` of the parent component
this.viewContainerRef.insert(component.hostView);
}
Note: The function createComponent()
was added only in Angular 14.2 (see CHANGELOG). The same feature is available also in ComponentFactory
(which is deprecated at the moment of writing).
See a similar example usage with ComponentFactory
:
constructor(
protected injector: Injector,
protected componentFactoryResolver: ComponentFactoryResolver,
protected viewContainerRef: ViewContainerRef
) {}
ngOnInit() {
// create a fresh element, detached from DOM
const hostElement = document.createElement('article');
const componentFactory =
this.componentFactoryResolver.resolveComponentFactory(MyComponent);
// create MyComponent, passing the `hostElement` param
const component = componentFactory.create(
this.injector,
undefined,
hostElement // <-----------------------------------
);
this.viewContainerRef.insert(component.hostView);
}
Here you can find also the working example on stackblitz using ComponentFactory
.
If you really feel like buying me a coffee
... then feel free to do it. Many thanks! 🙌
Top comments (0)