I am experimenting with Angular's custom elements and trying to avoid using Angular's dependency injection

const MyElementElement = createCustomElement(MyElementComponent, { injector });
customElements.define('my-element', MyElementElement);

However I am unable to create a custom element without passing in the injector

createCustomElement(MyElementComponent)

Is there a way to use the custom element without using Angular's dependency injection?

1 Answers

1
mwilson On

I am not sure what your createCustomElement function is doing, but if you're trying to dynamically add a component on the fly, this is the pattern you'll want to follow.

import { Component, ComponentFactoryResolver, OnInit, ViewChild, ViewContainerRef } from '@angular/core';

@Component({
    selector: 'app-something',
    templateUrl: './something.component.html',
    styleUrls: ['./something.component.scss']
})
export class SomethingComponent implements OnInit {
    @ViewChild('containerRef', { read: ViewContainerRef }) viewContainerRef: ViewContainerRef;
    private readonly _cfResolver: ComponentFactoryResolver;
    constructor(_cfr: ComponentFactoryResolver) {
        this._cfResolver = _cfr;
    }

    ngOnInit() {
        const componentFactory = this._cfResolver.resolveComponentFactory(MyComponent);
        const componentRef = this.viewContainerRef.createComponent(componentFactory);
        // Component Ref then has access to all it's properties
        // So you can then do things like
        // componentRef.instance.myComponentProperty = 'something';
    }
}

In your HTML, where you put the below tag is how you can control where the component gets inserted:

<ng-template #containerRef></ng-template>

Basically, in the component where you want to do 'dynamic stuff', import the ComponentFactoryResolver so you can create a component factory. Once you have that factory, you can then insert it into your component. If you do it this way, your injectors in the dynamic component will resolve. You don't have to pass anything in.

It's not as simple as doing new MyComponent(...)