Búsqueda de sitios web

typescript - Detectar cambio de propiedad dentro del componente en Angular


Estoy aprendiendo más sobre Angular y estoy tratando de ejecutar un método después de cambiar una propiedad. Este es mi código

isLoading = false;

ngOnInit() {
    this.isLoading = true;
    this._myService.getContent().subscribe(
        (response: IContent) => {
            this.isLoading = false;
            this.doSomething();
            // console.log(response);
        },
        err => {
            this.isLoading = false;
            this.doSomething();
            console.log(err);
        }
    );
}

doSomething() {
     console.log('some thing')
}

Y con esto quiero ejecutar doSomething() después de que isLoading se establezca en false (como poniendo por ejemplo .then(() => {this.doSomething()}) después de establecerlo). Sé que puedo poner doSomething() en un timeout como

setTimeout(() => this.doSomething(),10);

y eso funcionará, pero creo que hay una mejor manera. He buscado una solución y encontré sobre ChangeDetectorRef, del cual no estoy seguro de cómo implementarlo en este caso. También podría haber un enfoque diferente con el que no estoy familiarizado.

Respuesta #1

En su caso, doSomething debería llamarse después de que el Observable haya completado. Puede usar el pipe finalize para eso:

isLoading = false;

ngOnInit() {
  this.isLoading = true;

  this._myService.getContent().pipe(
    finalize(() => {
      this.isLoading = false;
      this.doSomething();
    })
  ).subscribe({
    next: (response: IContent) => console.log(response),
    error: (error: any) => console.log(err)
  });
}

doSomething() {
     console.log('some thing')
}

Si quieres -siempre- ejecutar doSomething() al establecer this.isLoading en false. Puedes usar un getter/setter:

get isLoading(): boolean {
  return this._isLoading;
}

set isLoading(loading: boolean) {
  this._isLoading = loading;

  if (loading) {
    this.doSomething();
  }
}

private _isLoading: boolean;

O simplemente puedes usar un método extra en tu clase:

setLoading(loading: boolean): void {
  this.loading = loading;

  if (loading) {
    this.doSomething();
  }
}

Sin embargo, las dos últimas opciones están mal vistas, porque las funciones ya no son puras, ya que lo más probable es que introduzcan efectos secundarios

Respuesta #2

Por favor, intenta implementar onPush o ChangeDetectionStrategy en tu componente

Hacer esto instruirá a Angular para que ejecute la detección de cambios en estos componentes y su subárbol solo cuando se les pasen nuevas referencias, en lugar de cuando los datos simplemente se mutan.

Ejecute this.ref.markForCheck() o this.ref.detectChanges() cuando actualice su variable (o haga algo) y quiera que se refleje en el html

Por favor, consulte los siguientes enlaces para más información

https://angular.io/api/core/ChangeDetectionStrategy

https://alligator.io/angular/change-detection-strategy/