zoukankan      html  css  js  c++  java
  • [RxJS] Reactive pattern: Passing Observable and trigger side effect until it complete

    For example, we want to show loading spinner inside our appliction component trees. Because we might trigger loading spinner anywhere inside our application, therefore, we need to use a loading.service.ts to communciate between different compnents.

    loading.service.ts:

    import {Injectable} from '@angular/core';
    import {BehaviorSubject, Observable, of} from 'rxjs';
    import {concatMap, finalize, tap} from 'rxjs/operators';
    
    @Injectable()
    export class LoadingService {
    
      private loadingSubject = new BehaviorSubject<boolean>(false);
    
      loading$: Observable<boolean> = this.loadingSubject.asObservable();
    
      loadingOn() {
        this.loadingSubject.next(true);
      }
    
      loadingOff() {
        this.loadingSubject.next(false);
      }
    
      showLoaderUntilCompleted<T>(obs$: Observable<T>): Observable<T> {
        return of(null)
          .pipe(
            tap(() => this.loadingSubject.next(true)),
            concatMap(() => obs$),
            finalize(() => {
              this.loadingSubject.next(false);
            })
          );
      }
    }

    Component:

    import { Component, OnInit } from '@angular/core';
    import {Observable} from 'rxjs';
    import {LoadingService} from './loading.service';
    
    @Component({
      selector: 'loading',
      template: '<div class="spinner-container" *ngIf="loading$ | async"><mat-spinner></mat-spinner></div>'
    })
    export class LoadingComponent implements OnInit {
    
      loading$ : Observable<boolean>;
      constructor(private loadingService: LoadingService) {
    
      }
    
      ngOnInit() {
    
        this.loading$ = this.loadingService.loading$;
      }
    }

    The most important thing to understand here is the function: showLoaderUntilComplete(obs$). 

    It takes a Observable, because we want to wait 'obs$' to complete, therefore, we use 'concatMap', it executes observable one by one, then we use 'finalize' operator, it will execute callback function when the observable completes. Here means waiting 'obs$' to be completed.

    How to use it?

    courses.service.ts

    private subject = new BehaviorSubject<Course[]>([]);
    
    courses$ = this.subject.asObservable();  
    
    private loadAllCourses() {
    
          const loadCourses$ =  this.http.get<Course[]>('/api/courses')
            .pipe(
              map(response => response["payload"])
            );
    
          this.loading.showLoaderUntilCompleted(loadCourses$)
            .subscribe(
              courses => this.subject.next(courses)
            );
      }
  • 相关阅读:
    MySQL概述
    Seleniumselenium基础入门
    MySQL数据库的安装与使用
    元素定位_id
    Selenium浏览器的前进、后退、刷新
    元素定位_tag_name
    Selenium浏览器操作_窗口大小设置
    元素定位_name
    搭建maven服务器(repository)
    使用dos命令生成目录树
  • 原文地址:https://www.cnblogs.com/Answer1215/p/12431901.html
Copyright © 2011-2022 走看看