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)
            );
      }
  • 相关阅读:
    Chromium 和Webkit 3月14日的最近进展:多标签选择、标签标题省略、动画API和新的Chromium Logo
    奇妙的HTML5 Canvas动画实例
    XNA那些事(一) 框架工作原理
    实现跨浏览器的HTML5占位符
    编写超级可读代码的15个最佳实践
    谈HTML5和CSS3的国际化支持
    HTML5 Guitar Tab Player
    如何设置让网站禁止被爬虫收录?robots.txt
    YourPHP笔记
    Robots.txt  禁止爬虫
  • 原文地址:https://www.cnblogs.com/Answer1215/p/12431901.html
Copyright © 2011-2022 走看看