关于RxJS 自定义封装Rxbus的使用规范文档

2018-09-12 15:41:52 浏览数 (1)

相关RX文章请看: SNS项目笔记<七>--深入探究RXjs SNS项目笔记<四>--RXjs简要用法

1、封装的provider代码:
代码语言:javascript复制
import { Injectable } from '@angular/core';
import 'rxjs/add/operator/map';
import { Subject } from "rxjs/Subject";
import { Observable } from 'rxjs/Observable';
import { ToastController } from 'ionic-angular';

/*
  Generated class for the Rxbus provider.

  See https://angular.io/docs/ts/latest/guide/dependency-injection.html
  for more info on providers and Angular DI.
*/
@Injectable()
export class Rxbus{

    private data: any; // 自定义bean 用来判断收发信息类型,隔离多事件重复问题
    private readonly subject: MySubject = MySubject.Instance //单例观察者

    constructor(){
         
    }
    /**
     * set监听
     * @param data 指定用于判断类型的bean 
     */
    setListener(data: any): void {
        this.data = data;
        this.subject.next(data);
    }
    /**
     * get监听对象
     */
    getListener(): Observable<any> {
        console.log(this.subject.observers);
        return this.subject.asObservable();
    }

    /**
     * 完成删除最后一个监听
     */
    compelete(){
        this.subject.finish()
    }
    /**
     * 完成清理所有监听
     */
    clear(){
        this.subject.clear()
    }
}


/**
 * 自定义观察者单例对象
 */
export class MySubject extends Subject<any> {
    public static readonly Instance: MySubject = new MySubject();
    
    private constructor(){
         super()
    }

    finish(){
        if (this.closed) {
            return
        }
        let len = this.observers.length;
        this.observers.splice(len-1,1);
    }

    clear(){
        if (this.closed) {
            return
        }
        this.observers.length = 0
    }
}
2、page页面使用说明:

2.1、使用准备:

代码语言:javascript复制
  //判断是否是进入子页面操作,如果是则为true,不是则为false,默认为false
  isInner:boolean = false
  
  //页面构造中传入provider
  constructor(public rxbus: Rxbus){}

2.2、生命周期方法:

代码语言:javascript复制
// 每次页面重新显示的时候都会调用
ionViewDidEnter() {
    this.isInner = false; // 判断是否进入子页面
}

// 页面每次成功加载后所调用的生命周期方法,在这个页面里面注册监听
ionViewDidLoad() {
    // 实例,不同类型和不同tag或者flag进行判断获取响应的监听结果
    this.rxbus.getListener().subscribe(data => {
      if (data instanceof RefreshTodo && data.tag == "uploadPhoto") {
        this.index = 1;
        this.isLoading = false;
        this.enable = true
        this.doNet(false)
      } else if (data instanceof RefreshTodo && data.tag == "refresh") {
        this.navCtrl.pop()
      } else if (data instanceof PopData && data.msg == "delete") {
        let photo = data.value
        this.deletePhoto(photo)
      } else if (data instanceof RefreshTodo && data.tag == "toUpdate") {
        let bean:AlbumBean = data.value
        this.albumName = bean.name
        this.bean.albumName = bean.name
        this.bean.logoUrl = bean.imgUrl
        this.bean.publicLevel = bean.permission
      }
    })

  }

//当页面不显示的时候使用该方法来删除本页面的监听,进入子页面则不应该删除监听
 ionViewDidLeave() {
    if (!this.isInner) {
      this.rxbus.compelete()
    }
  }

2.3、声明isInner为true的情况:

主要是在push页面之前,即进入子页面:

代码语言:javascript复制
    onClick($event){
        this.isInner = true
        this.nav.push(myChildPage)
    }
3、其他注意事项:

3.1、关于RXjs封装说明:由于源代码中仅通过叠加observer来创建监听者,并没有通过map或者类似于对象来储存所以必须在注册过后删掉以保持单例。

3.2、必须用不同的对象或者不同的tag以及value来区分所对应的监听,不然会出现重复监听情况。

3.3、必须在子页面(除了首页)删掉对应的监听,不然绝对会出现重复监听情况。

3.4、由于源码的局限性,重复监听与删除监听必须同步进行。

3.5、如果该页面有popWindow或者alert子页面以及modal页面的情况下,不能够使isInner变为true,不然会让监听无法删除,子页面的所有UI元素窗口没有走生命周期方法。

0 人点赞