• Angular中利用rxjs库的Subject多播解决在第一次订阅时进行初始化操作(如第一次订阅时从服务器获取数据)


    rxjs 库中 Subject 类可以用于实现多播,其本身已经有多个实现(可参考【Rxjs】 - 解析四种主题Subject),但是都是需要手动操作Subject对象进行发布。

    这里通过继承 BehaviorSubject(Subject的实现类,也可以直接继承Subject,但这里考虑到可能会用到初始值的时候)实现在第一次订阅(调用subscribe方法)时进行初始化(可以从服务器获取数据)。

    第一步: InitSubject 类定义
    import {BehaviorSubject, Subscriber, Subscription} from 'rxjs';
    
    /**
     * 第一次订阅时执行初始化操作.
     */
    export class InitSubject<T> extends BehaviorSubject<T> {
      /**
       * 是否为第一次
       */
      private first = true;
    
      constructor(initValue: T, private init: () => void = () => {}) {
        super(initValue);
      }
    
      /** @deprecated This is an internal implementation detail, do not use. */
      _subscribe(subscriber: Subscriber<T>): Subscription {
        if (this.first) {
          this.first = false;
          if (typeof this.init === 'function') {
            this.init();
          }
        }
        return super._subscribe(subscriber);
      }
    
    }
    第二步: Service中定义可观察对象
    import {Injectable} from '@angular/core';
    import {InitSubject} from '../InitSubject';
    import {HttpClient} from '@angular/common/http';
    import {retry} from 'rxjs/operators';
    
    /**
     * 获取配置系统管理的应用列表等.
     */
    @Injectable({
      providedIn: 'root'
    })
    export class AppService {
      /**
       * 用于发布信息,这里构造方法第二个参数传入自定义初始化逻辑.
       */
      public app$ = new InitSubject<Array<InternalApp>>(null, () => {
        this.http.get<any>('/get_xxx').pipe(retry(3))
            .subscribe(value => this.app$.next(value.data));
      });
    
      constructor(private http: HttpClient) {}
    }
    
    
    第三步: Service中定义可观察对象
    import {Component, OnDestroy, OnInit} from '@angular/core';
    import {AppService} from '../../service/app.service';
    import {Subscription} from 'rxjs';
    
    @Component({
      selector: 'app-home',
      templateUrl: './home.component.html',
      styleUrls: ['./home.component.less']
    })
    export class HomeComponent implements OnInit, OnDestroy {
      // 应用信息
      app: Array<any>;
      // 应用信息变更监听
      appSubscription: Subscription;
    
      constructor(private appService: AppService) { }
    
      ngOnInit(): void {
        // 初始化时定义订阅并监听数据变化
        this.appSubscription = this.appService.app$.subscribe(value => this.app = value);
      }
      ngOnDestroy(): void {
        // 销毁时取消订阅,防止内存泄露
        this.appSubscription.unsubscribe();
      }
    
    }
  • 相关阅读:
    linux-centos7 安装 maven 代码管理工具,以及常见配置
    linux-centos7 安装 jre + tomcat 实现 web 服务器
    python 开发语言 博客目录
    生存分布函数
    债务偿还
    密度聚类算法
    POI兴趣点搜索
    区域地址搜索
    地址之间的距离
    地理坐标转换
  • 原文地址:https://www.cnblogs.com/laeni/p/12823166.html
Copyright © 2020-2023  润新知