Введение в RxJS

Главная » Видеоуроки » JavaScript » Введение в RxJS
В этом уроке мы разберем базовые принципы RxJS. Эта отдельная библиотека, но в контексте angular устанавливается вместе с ним. RxJS используется во многих Angular аспектах: http клиент, реактивные формы, роутер.
Основной принцип RxJS — реакитвное программирование. В его основе поток данных, а также наблюдаемая сущность и наблюдатели.
Простой пример: вы нажимаете на кнопку «Купить», добавляется товар (поток). Компонент «Корзина» подписывается на изменение (subscribe), и происходит обновление данных (общая сумма и количество товаров).

RxJS упрощает работу с асинхронным кодом в сравнении с колбэками и промисами. В уроке мы рассмотрим практические применения RxJS, операторы (очень важная часть работы с потоками) и другие вопросы (например, горячие и холодные observables).

app.ts

import {Component, DestroyRef, inject, OnDestroy, OnInit} from '@angular/core';
import {User, UserService} from './user-service';
import {debounceTime, filter, Observable, of, Subject, Subscription, takeUntil} from 'rxjs';
import {AsyncPipe} from '@angular/common';
import {FormControl, ReactiveFormsModule} from '@angular/forms';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
import {UsersList} from './users-list/users-list';

@Component({
  selector: 'app-root',
  templateUrl: './app.html',
  imports: [
    ReactiveFormsModule,
    AsyncPipe,
    UsersList
  ],
  styleUrl: './app.scss'
})
export class App implements OnInit {

  protected users: User[] = [];
  protected users$!: Observable<User[]>;

  protected search = new FormControl<string>('');

  protected sub = new Subscription();

  protected destroy$!: Subject<any>;

  public obs = of(1,2,3);

  public subj = new Subject<number>();


  protected destroyRef = inject(DestroyRef);

  constructor(private userService: UserService) {
  }

  public ngOnInit() {
   this.userService.getUsers().pipe(
     takeUntilDestroyed(this.destroyRef)
   ).subscribe();

   this.users$ = this.userService.getUsers();


   this.search.valueChanges.pipe(
     filter(query => !!query?.trim()),
     debounceTime(500),
     takeUntilDestroyed(this.destroyRef),
   ).subscribe()

    // this.obs.subscribe(v => console.log('Подписчик первый', v));
    // this.obs.subscribe(v => console.log('Подписчик второй', v));

    this.subj.subscribe(v => console.log('Подписчик 1', v));
    this.subj.next(1);

    this.subj.subscribe(v => console.log('Подписчик 2', v));

    this.subj.next(2);

  }

  protected addUser() {
    const newUser = this.search.value;

    if (newUser) {
      const currentUsers = this.userService.users$.getValue();
      currentUsers.push(newUser);
      this.userService.users$.next(currentUsers);
    }
  }

}

app.html

<!--<ul>-->
<!--  @for (user of users; track user.id) {-->
<!--    <li>{{user.name}}</li>-->
<!--  }-->
<!--</ul>-->

@let users = users$ | async;

{{users?.length}}

<ul>
  @for (user of users; track user.id) {
    <li>{{user.name}}</li>
  }
</ul>


<input type="text" [formControl]="search">
<button (click)="addUser()">Add user</button>

<div>
  <app-users-list></app-users-list>
</div>

user-service.ts

import {inject, Injectable} from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {BehaviorSubject, catchError, forkJoin, filter, fromEvent, map, Observable, of, ReplaySubject, Subject, tap} from 'rxjs';

export interface User {
  id: number,
  name: string;
  username: string;
  email: string;
  address: Record<string, string>;
  phone: string;
  website: string;
  company: Record<string, string>;
}

@Injectable({
  providedIn: 'root',
})
export class UserService {

  protected http = inject(HttpClient);

  public users$ = new BehaviorSubject<string[]>([]);

  getUsers() {
    return this.http.get<User[]>('https://jsonplaceholder.typicode.com/users')
      .pipe(
        map(data => data),
      )
  }

}

user-list.ts

import {Component, OnInit} from '@angular/core';
import {JsonPipe} from '@angular/common';
import {UserService} from '../user-service';

@Component({
  selector: 'app-users-list',
  imports: [
    JsonPipe
  ],
  templateUrl: './users-list.html',
  styleUrl: './users-list.scss',
})
export class UsersList implements OnInit{

  protected users: string[] = [];

  constructor(private usersService: UserService) {
  }

  public ngOnInit() {
    this.usersService.users$.subscribe(res => this.users = res);
  }

}

user-list.html

Users length: {{users | json}}

0 Comments

Submit a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *


Срок проверки reCAPTCHA истек. Перезагрузите страницу.

Pin It on Pinterest

Share This