rx-utils
Paquete: @tiendana/ngx-core/ui
Dos helpers de RxJS que envuelven MutationObserver e IntersectionObserver en un Observable: fromMutationObserver y fromIntersectionObserver. tdn-select, tdn-input-date y tdn-input-time usan internamente fromIntersectionObserver para saber cuándo su control es visible.
Características
✅ El observer se crea al suscribirse y se desconecta al cancelar la suscripción
✅ Cada emisión entrega el arreglo de registros del navegador (MutationRecord[] o IntersectionObserverEntry[])
✅ Se componen con cualquier operador de RxJS y con takeUntilDestroyed
✅ Funciones puras, sin inyección de dependencias
fromMutationObserver
function fromMutationObserver(
target: Node,
config?: MutationObserverInit
): Observable<MutationRecord[]>
| Parámetro | Tipo | Descripción |
|---|---|---|
target | Node | Nodo del DOM a observar |
config | MutationObserverInit | Opciones del MutationObserver (por ejemplo { childList: true }) |
Retorno: un Observable que emite el arreglo de MutationRecord en cada callback del observer.
import { fromMutationObserver } from '@tiendana/ngx-core/ui';
fromMutationObserver(document.body, { childList: true, subtree: true })
.subscribe(records => console.log('DOM changed', records));
fromIntersectionObserver
function fromIntersectionObserver(
target: Element,
options?: IntersectionObserverInit
): Observable<IntersectionObserverEntry[]>
| Parámetro | Tipo | Descripción |
|---|---|---|
target | Element | Elemento del DOM cuya visibilidad se observa |
options | IntersectionObserverInit | Opciones documentadas del helper (por ejemplo { threshold: 0.5 }) |
Retorno: un Observable que emite el arreglo de IntersectionObserverEntry en cada cambio de intersección.
import { fromIntersectionObserver } from '@tiendana/ngx-core/ui';
fromIntersectionObserver(elementRef.nativeElement)
.subscribe(entries => console.log('Visibility changed', entries));
options no se aplica en 0.9.0En la versión 0.9.0 el helper acepta options pero no lo pasa al constructor de IntersectionObserver, que se crea con las opciones por defecto (viewport como raíz, umbral 0). Si necesitas root, rootMargin o threshold, crea el IntersectionObserver tú mismo hasta que se corrija.
Uso en un componente
Combina el helper con takeUntilDestroyed y filtra la entrada que te interesa:
import { Component, ElementRef, inject, signal } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { map } from 'rxjs';
import { fromIntersectionObserver } from '@tiendana/ngx-core/ui';
@Component({
selector: 'app-lazy-block',
template: `@if (visible()) { <app-heavy-content /> }`
})
export class LazyBlockComponent {
private readonly host = inject(ElementRef<HTMLElement>);
readonly visible = signal(false);
constructor() {
fromIntersectionObserver(this.host.nativeElement)
.pipe(
map(entries => entries.some(entry => entry.isIntersecting)),
takeUntilDestroyed()
)
.subscribe(visible => this.visible.set(visible));
}
}
Notas
- El observer empieza a observar en la suscripción: sin suscriptores no hay costo.
- Al cancelar la suscripción se llama a
disconnect(), así que no queda ningún observer vivo. - Cada suscripción crea su propio observer. Comparte el resultado con
share()si varios consumidores observan el mismo nodo.
Ver También
whenScrolled: detección de fin de scroll para infinite scroll