///仅供学习使用
Create Observer
comn.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ComnService {
constructor() { }
public storeObj={};
set(key,value){
this.storeObj[key]=value
}
get(key){
return this.storeObj[key];
}
}
app-get-value.ts
import { Observable } from 'rxjs';
let OBS: Observable<any> = new Observable(observer => {
//公共方法里获取数据
let params = this.comnService.get('data')
if (params) {
this.title = params.title
console.log(params)
}
observer.next(params);
})
//将obs对象存起来,其他地方消费
this.comnService.set('OBSR', OBS)
app-set-value.ts
this.OBS = this.comnService.get('OBSR');
this.comnService.set('data', {
type: 'set-title',
title: new_title
});
//上面修改值后 调用subscribe 来通知发布者,在app-get-value.ts会自动监听到变化,来执行响应操作
this.OBS.subscribe((res) => {
console.log(res)
});
Event Observer
import { fromEvent } from 'rxjs';
import { map } from 'rxjs/operators';
// 创建发出点击事件的 observable
const source = fromEvent(document, 'click');
// 映射成给定的事件时间戳
const example = source.pipe(map(event => `Event time: ${event.timeStamp}`));
// 输出 (示例中的数字以运行时为准): 'Event time: 7276.390000000001'
const subscribe = example.subscribe(val => console.log(val));
监听页面
import { Observable } from 'rxjs';
import {HostListener} from '@angular/core';
// 监听页面大小变化
Observable.fromEvent(window, 'resize').subscribe((event) => {
console.log('页面变化了');
console.log(event);
});
// 监听页面刷新
Observable.fromEvent(window, 'beforeunload').subscribe((event) => {
console.log('页面刷新了');
console.log(event);
});
@HostListener('window:resize', ['$event'])
onResize(event) {
event.target.innerWidth;
}
观察者模式:定义了对象间一种一对多的依赖关系,当目标对象 Subject 的状态发生改变时,所有依赖它的对象 Observer 都会得到通知。
优点 :
- 目标者与观察者,功能耦合度降低,专注自身功能逻辑;
- 观察者被动接收更新,时间上解耦,实时接收目标者更新状态;
缺点 :
- 不能对事件通知进行细分管控,如 “筛选通知”,“指定主题事件通知” 。
- 观察者对象不能只接收自己需要的更新通知 , 目标对象会通知所有观察者;
// 目标者类
class Subject {
constructor() {
this.observers = []; // 观察者列表
}
// 添加
add(observer) {
this.observers.push(observer);
}
// 删除
remove(observer) {
let idx = this.observers.findIndex(item => item === observer);
idx > -1 && this.observers.splice(idx, 1);
}
// 通知
notify() {
for (let observer of this.observers) {
observer.update();
}
}
}
// 观察者类
class Observer {
constructor(name) {
this.name = name;
}
// 目标对象更新时触发的回调
update() {
console.log(`目标者通知我更新了,我是:${this.name}`);
}
}
// 实例化目标者
let subject = new Subject();
// 实例化两个观察者
let obs1 = new Observer('小王');
let obs2 = new Observer('小李');
// 向目标者添加观察者
subject.add(obs1);
subject.add(obs2);
// 目标者通知更新
subject.notify();
// 输出:
// 目标者通知我更新了,我是小王
// 目标者通知我更新了,我是小李
发布订阅模式(Publisher && Subscriber):基于一个事件(主题)通道,希望接收通知的对象 Subscriber 通过自定义事件订阅主题,被激活事件的对象 Publisher 通过发布主题事件的方式通知各个订阅该主题的 Subscriber 对象。
// 事件中心
let pubSub = {
list: {},
subscribe: function (key, fn) { // 订阅
if (!this.list[key]) {
this.list[key] = [];
}
this.list[key].push(fn);
},
publish: function(key, ...arg) { // 发布
for(let fn of this.list[key]) {
fn.call(this, ...arg);
}
},
unSubscribe: function (key, fn) { // 取消订阅
let fnList = this.list[key];
if (!fnList) return false;
if (!fn) {
// 不传入指定取消的订阅方法,则清空所有key下的订阅
fnList && (fnList.length = 0);
} else {
fnList.forEach((item, index) => {
if (item === fn) {
fnList.splice(index, 1);
}
})
}
}
}
// 订阅
pubSub.subscribe('onwork', time => {
console.log(`上班了:${time}`);
})
pubSub.subscribe('offwork', time => {
console.log(`下班了:${time}`);
})
pubSub.subscribe('launch', time => {
console.log(`吃饭了:${time}`);
})
// 发布
pubSub.publish('offwork', '18:00:00');
pubSub.publish('launch', '12:00:00');
// 取消订阅
pubSub.unSubscribe('onwork');
类似例子 DOM事件监听 vue 父子传值 pubsub.js 事件总线等
网友评论