相关RX文章请看: SNS项目笔记<七>--深入探究RXjs SNS项目笔记<四>--RXjs简要用法
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.1、使用准备:
//判断是否是进入子页面操作,如果是则为true,不是则为false,默认为false
isInner:boolean = false
//页面构造中传入provider
constructor(public rxbus: Rxbus){}
2.2、生命周期方法:
// 每次页面重新显示的时候都会调用
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页面之前,即进入子页面:
onClick($event){
this.isInner = true
this.nav.push(myChildPage)
}
3.1、关于RXjs封装说明:由于源代码中仅通过叠加observer来创建监听者,并没有通过map或者类似于对象来储存所以必须在注册过后删掉以保持单例。
3.2、必须用不同的对象或者不同的tag以及value来区分所对应的监听,不然会出现重复监听情况。
3.3、必须在子页面(除了首页)删掉对应的监听,不然绝对会出现重复监听情况。
3.4、由于源码的局限性,重复监听与删除监听必须同步进行。
3.5、如果该页面有popWindow或者alert子页面以及modal页面的情况下,不能够使isInner变为true,不然会让监听无法删除,子页面的所有UI元素窗口没有走生命周期方法。