Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

232
Visualizações
¿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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda