Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

229
Vistas
How do I dynamically create components with third party library in Angular?

Using Angular 10

There are many questions on SO that are similar to this, but I have yet to find one that answers my situation.

I'm hoping someone can guide me.

I'm using a third party library to display 360° photos. This third party library has a built-in API to display hotspots in the scene. Simply give the library the element you want to be the hotspot, and it takes care of the rest.

I have most of it working as expected, but there are a couple pieces that are not.

So far, I'm dynamically generating my components like so:

this._hotspotFactory = this.resolver.resolveComponentFactory(HotspotComponent);
const component = this._hotspotFactory.create(this.injector);

//Hydrate component with  bunch of data
component.instance.id = data.id;
...

// Create the Hotspot with Third Party
// Calling this third party method injects the native element into the DOM. 
// Passing the nativeElement in. Looks great at first glance. 
const hotspot = this._scene.createHotspot(data, component.location.nativeElement);

this.appRef.attachView(component.hostView);
component.hostView.detectChanges();

if(component.instance.over.observers.length) {
  hotspot.on('over', (evt) => {
    this.zone.run(() => {
      component.instance.over.emit(evt);
    });
  });
}

if(component.instance.out.observers.length) {
  hotspot.on('out', (evt) => {
    this.zone.run(() => {
      component.instance.out.emit(evt);
    });
  });
}

if(component.instance.navigate.observers.length) {
  hotspot.on('click', (evt) => {
    this.zone.run(() => {
      component.instance.navigate.emit(evt);
    })
  });
}

No errors are thrown and I successfully see the hotspot where it should be in the scene. Even Data interpolation in the HotspotComponent template occurs as expected.

BUT, [ngStyle] bindings never result in dynamic styling in HotspotComponent.

I'm 99% sure this is because change detection is not taking place in the component.

I am manually attaching the view with this.appRef.attachView(component.hostView) because the third party is responsible for injecting the element into the DOM, not Angular. Thus Angular needs to know about it so it will perform change detection.

Even with manually calling attachView, I still think Angular doesn't know about this component in the view because the Angular Chrome Extension debugger doesn't register it in its dev tools as a known component in the view....despite be seeing it on screen and in the DOM.

What am I missing?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

What change detection strategy does the component have? When a component is added to a view, it's life cycle hooks will be triggered by angular(ngOninit, ngAfterContentInit etc). Log something in these and see if theme life cycle hooks are being called. Irrespective of the change detection strategy one change detection cycle should happen on the component after it is added to view.

If the life cycle hook invoking is not happening, then it would mean that angular is not involved in adding the element to DOM.

over 4 years ago · Santiago Trujillo Denunciar

0

It seems angular has a lifecycle hook precisely for your use-case 'ngDoBootstrap'.

As we can not debug your full source code, from the information you have mentioned it seems the dynamic component you are trying to attach to the view is not available to Angular in NgModule. Every component that angular bootstraps must be in NgModule.

you can although bootstrap it dynamically using 'ngDoBootstrap'.

It is used in the following manner:

ngDoBootstrap(appRef: ApplicationRef) {

      this.fetchDataFromApi().then((componentName: string) => {
        if (componentName === 'ComponentOne') {
          appRef.bootstrap(ComponentOne);
        } else {
          appRef.bootstrap(ComponentTwo);
        }
      });
    }

In your case, you can do it before attaching the component to the view.

...
appRef.bootstrap(component);
this.appRef.attachView(component.hostView);
component.hostView.detectChanges();
...

Please check the documentation here: https://angular.io/api/core/ApplicationRef

over 4 years ago · Santiago Trujillo Denunciar

0

We use resolveComponentFactory method given by ComponentFactoryResolver class present in angular which is used for component level lazy loading. For the confirmation that your component is really breaked in chunks, do ng build --prod or you con and you will see the generated .js chunk for SoftwareListComponent.

app.component.html

  <button (click)="loadSoftwareListDynamically()> Load </button>
  <div #softwareListContainer></div>

app.component.ts

   constructor(
    private componentFactoryResolver: ComponentFactoryResolver
  ) {}

  @ViewChild('softwareListContainer', { read: ViewContainerRef })
  softwareListContainer: ViewContainerRef;

  loadSoftwareListDynamically() {
    import('../common-features/software-list/software-list.component').then(
      ({ SoftwareListComponent }) => {
        const componentFactory =
          this.componentFactoryResolver.resolveComponentFactory(
            SoftwareListComponent
          );
        this.softwareListContainer.createComponent(componentFactory);
      }
    );
  }

software-list.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

@NgModule({
  declarations: [
   SoftwareListComponent
  ],
  imports: [
    CommonModule,
    RouterModule,
    SwiperModule    <- External Library
  ],
})
export class SoftwareListModule {}

For more info, you can go over to my complete discussion for Lazy loading of components created using ComponentFactoryResolver. You will get more info here -> StackOverflow Discussion

Stackblitz Link Here

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda