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

1.3K
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar

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 Denunciar

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 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