Resumen de la aplicación RXJS en Angular (Parte 1)


prefacio

En el proyecto de sistema de información de gestión (MIS) de Angular, RxJS tiene principalmente los siguientes escenarios de aplicación comunes:
(Este artículo presenta las tres primeras escenas)

Operaciones asíncronas : la función principal de RxJS es manejar operaciones asíncronas, como iniciar solicitudes HTTP, setTimeout, WebSocket, etc.

Gestión de estado : BehaviorSubject se puede utilizar para crear un flujo de datos observable, que es muy útil para la gestión de estado. Por ejemplo, puede usarlo para compartir el estado de inicio de sesión de un usuario, la configuración del tema y más.

Manejo de formularios : el módulo de formularios de Angular funciona muy bien con RxJS. Por ejemplo, cuando cambia el valor de un formulario, puede usar valueChanges Observable, combinado con debounceTime, filter, map y otros operadores para la validación de formularios complejos.

Gestión de enrutamiento : el módulo de enrutador de Angular proporciona una serie de eventos observables, puede suscribirse a estos observables para manejar el inicio, el final, la cancelación de la navegación de enrutamiento y otros eventos.

Comunicación : si su aplicación necesita usar Websocket o Server-Sent Events, RxJS proporciona una manera fácil de manejar estos procesos de comunicación.

Interacción de la interfaz de usuario : RxJS se puede usar para manejar interacciones de usuario complejas, como operaciones de rebote y aceleración, arrastrar y soltar, etc.

Manejo de errores : con RxJS, puede manejar errores y reintentos fácilmente. Por ejemplo, si falla una solicitud HTTP, puede usar los operadores reintentar o reintentar cuando para volver a intentarlo.

Combine varias operaciones asincrónicas : con operadores como forkJoin, combineLatest o zip, puede combinar varios Observables y esperar a que se completen.

Sondeo : si necesita verificar periódicamente los cambios de datos en el servidor, puede usar la función de intervalo o temporizador combinada con el operador switchMap para crear un sondeo.


提示:以下是本篇文章正文内容,下面案例可供参考

1. Operación asíncrona

Supongamos que queremos obtener datos de un servidor API y mostrarlos en la interfaz de usuario. Podemos usar el módulo HttpClient de Angular para iniciar solicitudes HTTP y luego usar componentes NG-ZORRO para mostrar datos.

Primero, creamos un servicio DataService para realizar solicitudes HTTP:

El código es el siguiente (ejemplo):

import {
    
     Injectable } from '@angular/core';
import {
    
     HttpClient } from '@angular/common/http';
import {
    
     Observable } from 'rxjs';

@Injectable({
    
    
  providedIn: 'root'
})
export class DataService {
    
    
  constructor(private http: HttpClient) {
    
    }

  getData(): Observable<any> {
    
    
    return this.http.get('https://api.example.com/data');
  }
}

Luego, creamos un componente DataComponent para mostrar los datos:

import {
    
     Component, OnInit } from '@angular/core';
import {
    
     DataService } from './data.service';

@Component({
    
    
  selector: 'app-data',
  template: `
    <nz-spin *ngIf="loading"></nz-spin>
    <nz-table [nzData]="data" *ngIf="!loading"></nz-table>
  `
})
export class DataComponent implements OnInit {
    
    
  data: any[] = [];
  loading = true;

  constructor(private dataService: DataService) {
    
    }

  ngOnInit() {
    
    
    this.dataService.getData().subscribe(
      data => {
    
    
        this.data = data;
        this.loading = false;
      },
      error => {
    
    
        console.error(error);
        this.loading = false;
      }
    );
  }
}

En este ejemplo, DataService usa el método get de HttpClient para realizar solicitudes HTTP. El método get devuelve un Observable que emite los datos devueltos por el servidor cuando la solicitud es exitosa.

Cuando se inicializa DataComponent, llama al método getData de DataService para obtener datos y se suscribe al Observable devuelto. Una vez que los datos se obtienen con éxito, asignamos los datos a la variable de datos y establecemos la variable de carga en falso para ocultar el indicador de carga. Si la solicitud falla, registramos el error en la consola y establecemos la variable de carga en falso.

En la plantilla del componente, usamos el componente nz-spin de NG-ZORRO para mostrar el indicador de carga y el componente nz-table para mostrar los datos. Cuando la variable de carga es verdadera, se muestra el indicador de carga; cuando la variable de carga es falsa, se muestra la cuadrícula de datos.

2. Gestión de estado

Primero, necesitamos crear un servicio para administrar el estado de inicio de sesión de los usuarios. En este ejemplo, usaremos un BehaviorSubject para representar el estado de inicio de sesión del usuario:

El código es el siguiente (ejemplo):

import {
    
     Injectable } from '@angular/core';
import {
    
     BehaviorSubject, Observable } from 'rxjs';

@Injectable({
    
    
  providedIn: 'root',
})
export class AuthService {
    
    
  private loggedIn = new BehaviorSubject<boolean>(false); // 默认用户未登录

  get isLoggedIn(): Observable<boolean> {
    
    
    return this.loggedIn.asObservable(); // 提供一个获取登录状态的 Observable
  }

  login(): void {
    
    
    // 假设登录验证通过
    this.loggedIn.next(true); // 更新登录状态
  }

  logout(): void {
    
    
    this.loggedIn.next(false); // 更新登录状态
  }
}

Luego, podemos usar AuthService en el componente para mostrar el estado de inicio de sesión del usuario y proporcionar botones de inicio y cierre de sesión:

import {
    
     Component, OnInit } from '@angular/core';
import {
    
     AuthService } from './auth.service';
import {
    
     NzMessageService } from 'ng-zorro-antd/message';

@Component({
    
    
  selector: 'app-login',
  template: `
    <div *ngIf="isLoggedIn | async; else loggedOut">
      <button nz-button nzType="primary" (click)="logout()">Logout</button>
    </div>
    <ng-template #loggedOut>
      <button nz-button nzType="primary" (click)="login()">Login</button>
    </ng-template>
  `,
})
export class LoginComponent implements OnInit {
    
    
  isLoggedIn: Observable<boolean>;

  constructor(private authService: AuthService, private message: NzMessageService) {
    
    }

  ngOnInit(): void {
    
    
    this.isLoggedIn = this.authService.isLoggedIn;
  }

  login(): void {
    
    
    this.authService.login();
    this.message.success('Logged in!');
  }

  logout(): void {
    
    
    this.authService.logout();
    this.message.success('Logged out!');
  }
}

En este ejemplo:

AuthService se usa para administrar el estado de inicio de sesión del usuario. Proporciona un Observable de isLoggedIn que permite que los componentes se suscriban al estado de inicio de sesión del usuario.
El componente LoginComponent usa el Observable isLoggedIn de AuthService para mostrar el estado de inicio de sesión del usuario y proporciona botones para iniciar y cerrar sesión.
Cuando el usuario hace clic en el botón de inicio o cierre de sesión, el componente llama al método de inicio o cierre de sesión de AuthService para actualizar el estado de inicio de sesión del usuario y muestra un mensaje mediante NzMessageService.
Usamos una canalización asíncrona para suscribirnos a isLoggedIn Observable para que Angular pueda administrar automáticamente la suscripción y evitar pérdidas de memoria.

BehaviorSubject es un concepto importante en RxJS, que es un tipo especial de sujeto. El sujeto se ve en RxJS como un objeto que es a la vez Observable (objeto observable) y Observer (observador). En otras palabras, puede enviarle (emitir) datos o suscribir (suscribir) datos desde él.

La principal diferencia entre un BehaviorSubject y un Subject normal es que recuerda el último valor enviado. Cuando un nuevo observador se suscribe, el nuevo observador recibirá inmediatamente el último valor enviado. Esto puede ser muy útil en muchas situaciones, por ejemplo, en este ejemplo, queremos que los nuevos suscriptores sepan de inmediato el estado actual de inicio de sesión del usuario.

Este código privado iniciado sesión = nuevo BehaviorSubject (falso); define una instancia de BehaviorSubject y establece el valor inicial en falso, lo que significa que el usuario no ha iniciado sesión. Este BehaviorSubject se puede usar para enviar nuevos estados de inicio de sesión y también se puede suscribir para recibir nuevos estados de inicio de sesión.

Luego, definimos un método getter isLoggedIn() que devuelve la versión Observable de login. Este método se implementa llamando a logIn.asObservable(), que devuelve un nuevo Observable que refleja todos los valores de logIn, pero no puede enviar nuevos valores a través de él. De esta manera, podemos proteger el inicio de sesión del envío accidental de nuevos valores fuera del servicio AuthService.

Por lo tanto, el propósito principal del método isLoggedIn en el servicio AuthService es proporcionar una forma segura para que el código externo se suscriba al estado de inicio de sesión del usuario sin preocuparse por cambiar accidentalmente el estado de inicio de sesión.

3. Procesamiento de formularios

Supongamos que tenemos un formulario para el registro de usuarios y necesitamos verificar si el nombre de usuario ya está registrado tan pronto como el usuario lo ingrese.

Primero, necesitamos importar ReactiveFormsModule y NgZorroAntdModule en el módulo Angular:

El código es el siguiente (ejemplo):

import {
    
     ReactiveFormsModule } from '@angular/forms';
import {
    
     NgZorroAntdModule } from 'ng-zorro-antd';

@NgModule({
    
    
  imports: [
    ReactiveFormsModule,
    NgZorroAntdModule,
    // ...
  ],
  // ...
})
export class AppModule {
    
     }

Luego, podemos crear un servicio para simular la llamada a la API:

import {
    
     Injectable } from '@angular/core';
import {
    
     of, Observable } from 'rxjs';
import {
    
     delay } from 'rxjs/operators';

@Injectable({
    
    
  providedIn: 'root'
})
export class UserService {
    
    
  checkUsername(username: string): Observable<boolean> {
    
    
    const isTaken = (username === 'user1');
    return of(isTaken).pipe(delay(500));
  }
}

A continuación, podemos crear el formulario en el componente y escuchar el valueChanges Observable del campo de nombre de usuario:

import {
    
     Component, OnInit } from '@angular/core';
import {
    
     FormGroup, FormBuilder } from '@angular/forms';
import {
    
     debounceTime, switchMap } from 'rxjs/operators';
import {
    
     UserService } from './user.service';

@Component({
    
    
  selector: 'app-register',
  templateUrl: './register.component.html',
  styleUrls: ['./register.component.css']
})
export class RegisterComponent implements OnInit {
    
    
  form: FormGroup;
  usernameTaken = false;

  constructor(private fb: FormBuilder, private userService: UserService) {
    
     }

  ngOnInit() {
    
    
    this.form = this.fb.group({
    
    
      username: '',
      password: '',
    });

    this.form.get('username').valueChanges.pipe(
      debounceTime(500),
      switchMap(username => this.userService.checkUsername(username))
    ).subscribe(isTaken => {
    
    
      this.usernameTaken = isTaken;
    });
  }
}

Finalmente, podemos usar los controles de formulario de NG-ZORRO y los componentes de tipografía nz en la plantilla para mostrar los resultados de la validación:

<form [formGroup]="form" nz-form>
  <nz-form-item>
    <nz-form-label nzRequired>Username</nz-form-label>
    <nz-form-control>
      <input nz-input formControlName="username" />
      <nz-typography *ngIf="usernameTaken" nzType="danger">Username is already taken</nz-typography>
    </nz-form-control>
  </nz-form-item>
  <nz-form-item>
    <nz-form-label nzRequired>Password</nz-form-label>
    <nz-form-control>
      <input nz-input formControlName="password" type="password" />
    </nz-form-control>
  </nz-form-item>
</form>

En este ejemplo, usamos las siguientes características de RxJS:

debounceTime(500): esperamos a que el usuario deje de escribir durante 500 milisegundos antes de realizar una solicitud de API para evitar un exceso de solicitudes de API.
switchMap: iniciamos una nueva solicitud de API después de cada entrada de usuario y cancelamos la última solicitud de API pendiente. De esta manera, siempre obtenemos el resultado de la validación del último nombre de usuario ingresado.


Supongo que te gusta

Origin blog.csdn.net/weixin_45876175/article/details/132050727
Recomendado
Clasificación