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

231
Vistas
¿Cómo creo dinámicamente componentes con una biblioteca de terceros en Angular?

Usando Angular 10

Hay muchas preguntas sobre SO que son similares a esta, pero todavía tengo que encontrar una que responda a mi situación.

Espero que alguien me pueda orientar.

Estoy usando una biblioteca de terceros para mostrar fotos de 360°. Esta biblioteca de terceros tiene una API integrada para mostrar puntos de acceso en la escena. Simplemente proporcione a la biblioteca el elemento que desea que sea el punto de acceso y ella se encargará del resto.

Tengo la mayor parte funcionando como se esperaba, pero hay un par de piezas que no funcionan.

Hasta ahora, estoy generando dinámicamente mis componentes así:

 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 se arrojan errores y veo con éxito el punto de acceso donde debería estar en la escena. Incluso la interpolación de datos en la plantilla HotspotComponent ocurre como se esperaba.

PERO, los enlaces [ngStyle] nunca dan como resultado un estilo dinámico en HotspotComponent .

Estoy 99% seguro de que esto se debe a que la detección de cambios no se lleva a cabo en el componente.

Adjunto manualmente la vista con this.appRef.attachView(component.hostView) porque el tercero es responsable de inyectar el elemento en el DOM, no en Angular. Por lo tanto, Angular necesita saberlo para que realice la detección de cambios.

Incluso llamando manualmente a attachView , sigo pensando que Angular no conoce este componente en la vista porque el depurador de Angular Chrome Extension no lo registra en sus herramientas de desarrollo como un componente conocido en la vista... a pesar de estar viéndolo en pantalla y en el DOM.

¿Qué me estoy perdiendo?

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

0

¿Qué estrategia de detección de cambios tiene el componente? Cuando se agrega un componente a una vista, angular ( ngOninit , ngAfterContentInit , etc.) activará sus ganchos de ciclo de vida. Registre algo en estos y vea si se están llamando a los ganchos del ciclo de vida del tema. Independientemente de la estrategia de detección de cambios, debe ocurrir un ciclo de detección de cambios en el componente después de agregarlo a la vista.

Si la invocación del gancho del ciclo de vida no está ocurriendo, entonces significaría que angular no está involucrado en agregar el elemento a DOM.

over 4 years ago · Santiago Trujillo Denunciar

0

Parece que angular tiene un gancho de ciclo de vida precisamente para su caso de uso 'ngDoBootstrap' .

Como no podemos depurar su código fuente completo, a partir de la información que mencionó, parece que el componente dinámico que está tratando de adjuntar a la vista no está disponible para Angular en NgModule. Cada componente que arranque angular debe estar en NgModule .

aunque puede arrancarlo dinámicamente usando 'ngDoBootstrap' .

Se utiliza de la siguiente manera:

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

En su caso, puede hacerlo antes de adjuntar el componente a la vista.

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

Consulte la documentación aquí: https://angular.io/api/core/ApplicationRef

over 4 years ago · Santiago Trujillo Denunciar

0

Usamos el método resolveComponentFactory proporcionado por la clase ComponentFactoryResolver presente en angular que se usa para la carga diferida a nivel de componente. Para confirmar que su componente está realmente dividido en fragmentos , haga ng build --prod o confíe y verá el fragmento .js generado para SoftwareListComponent .

aplicación.componente.html

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

aplicación.componente.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 {}

Para obtener más información, puede consultar mi discusión completa sobre la carga diferida de componentes creados con ComponentFactoryResolver . Obtendrá más información aquí -> Discusión de StackOverflow

Enlace de Stackblitz aquí

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