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)
            );
      }
  • 相关阅读:
    java中 Hex(十六进制)和byte[]相互转换
    byte[]和File相互转换
    Stringboot MultiPartFile 转 File
    mysql8.0+运行报错The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone. 解决办法
    idea激活
    mysql8安装成功过后navicat连接失败
    AJAX的使用
    单文件上传和多文件上传实例
    监听器的使用
    SQL分页技术
  • 原文地址:https://www.cnblogs.com/Answer1215/p/12431901.html
Copyright © 2011-2022 走看看