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

1.3K
Visualizações
Angular: espere hasta que todos los componentes secundarios se hayan renderizado antes de ejecutar el código

Tengo una directiva que está en el nivel superior de la aplicación y consulta elementos a través de document.querySelector y los entrega a fromEvent . El problema es que cuando se ejecuta el código en ngAfterViewInit de la directiva, el DOM aún no se representa por completo, por lo que la consulta del elemento devuelve un valor nulo.

Podría ejecutar el código en setTimeout con una cantidad de tiempo arbitraria, pero eso no parece una solución sostenible y flexible.

¿Alguna idea de cómo se puede manejar esto con elegancia?

En este momento, mi código parece una variación de esto:

 ngAfterViewInit() { const trackedEl = document.querySelector('#myInput'); const input$ = fromEvent(trackedEl, 'input') .pipe( map((inputEvent: any) => inputEvent.target.value) ) .subscribe((v) => { console.log(`Got to the observable:: ${v}`, count++); }) }
over 4 years ago · Santiago Trujillo
4 Respostas
Responde à pergunta

0

Creo que su mejor enfoque aquí sería usar algo como ViewChild .

Entonces, suponiendo que su querySelector apunta a una etiqueta <input> , su html sería como (observe el decorador #myInput):

 <input #myInput ....>

Su archivo .ts sería:

 @ViewChild('myInput', { static: true }) input?: ElementRef<HTMLElement>;

Entonces porque solo queremos resolver el evento cuando está suscrito a:

 const input$ = defer(() => fromEvent(this.input, 'input').pipe( map((inputEvent: any) => inputEvent.target.value) ) .subscribe((v) => { console.log(`Got to the observable:: ${v}`, count++); });

Algo en este sentido, pero ciertamente ViewChild es clave aquí.

over 4 years ago · Santiago Trujillo Relatório

0

El gancho de ciclo de vida ngAfterViewInit que angular llama después de crear todas las vistas secundarias del componente. Por lo tanto, debe implementarlo en el AppComponent raíz. Luego mantenga un observable en un servicio o estado y simplemente suscríbase a él en cualquier lugar que desee verificar.

Componente raíz de la aplicación:

 export class AppComponent implements AfterViewInit { title = "Angular App"; constructor(private data: DataService){} ngAfterViewInit() { this.data.rendered.next(true); } }

suscribiéndolo en cualquier lugar:

 export class HighlightDirective { constructor(private data: DataService) { this.data.rendered.subscribe(rendered => { // all components rendered here, write you code }); } }
over 4 years ago · Santiago Trujillo Relatório

0

Creo que esto podría ser un enfoque:

 ngAfterViewInit() { defer(() => fromEvent(document.querySelector('#myInput'), 'input')) .pipe( subscribeOn(asyncScheduler), map((inputEvent: any) => inputEvent.target.value) ) .subscribe((v) => { console.log(`Got to the observable:: ${v}`, count++); }) }

Este enfoque sigue recurriendo a algo como setTimeout , pero de una manera más elegante . Esto se logra usando defer + subscribeOn .

Al proporcionar asyncScheduler para subscribeOn , obtenemos una funcionalidad similar a setTimeout . El operador defer se ha utilizado porque queremos evaluar esa función que consulta el DOM cuando la fuente está suscrita, y recordar que el tiempo de suscripción es retrasado por el operador subscribeOn .
Entonces, en el momento en que se suscribe la fuente, el DOM debería estar listo para ser consultado.

Sé que esto es solo una solución para setTimeout , pero pensé que se vería más elegante con algunos operadores RxJS interesantes.

over 4 years ago · Santiago Trujillo Relatório

0

Terminé encontrando la solución que estaba buscando.

Los elementos secundarios no se procesaron a tiempo probablemente porque estaban respondiendo a algún evento http pendiente que aún no había devuelto una respuesta. Después de leer la documentación para la detección de cambios y ngZone , parecía que los eventos destacados de http cuentan como "microtareas".

El siguiente código es lo que funcionó para mí.

 ngOnInit() { this.ngZone.onMicrotaskEmpty.pipe(take(1)).subscribe((a) => { this.initiateElementEventListeners(); }); }
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