又让你痛不欲生,又让你趁醉装疯,终有天脱胎换骨,直到哭着笑才懂。欲问青天这人生有几何,有几何啊?
今年去城墙下转了一圈,想到这几年的工作,这几年的经历,我到底是图什么。也许你勇敢的跨出一步,就是这一步。发感慨也没啥用,实际行动才可以。
今天主要是看一下类似于观察者模式的广播通知,首先我们需要安装rxjs包。安装好之后,引入我们的项目。
import { Injectable } from '@angular/core'; import { Observable, Subject } from 'rxjs'; import { filter, map } from 'rxjs/operators'; @Injectable() export class BroadCaster { private subject: Subject<BroadCastEvent>; constructor() { this.subject = new Subject<BroadCastEvent>(); } broadcast(key: any, data?: any) { this.subject.next({ key, data }); } on<T>(key: any, data?: any) { return this.subject.asObservable() .pipe( filter(e => e.key === key), map(e => <T>e.data)) ; } } interface BroadCastEvent { key: any; data?: any }
首先我们定义好接口BroadCastEvent,包含两个属性。然后再定义通知类,通知类必须是可注入的,因此需要标记@Injectable。
在构造函数中先实例化Subject泛型类,注意这里的泛型类型就是我们定义的接口类型。
在这里主要有两个方法,broadcast,包含key和data参数。收到后调用subject的next方法,将消息传递给接收者。
然后我们还有个on方法,当别的模块发消息出来的收,我们会收到消息。这里我们有个pipe方法,第一个参数是过滤用的,举个例子。
还是洗浴中心,突击检查。此时前台只希望将消息通知到三楼洗浴场,四楼宾馆。此时就需要判断通知是不是给三四楼发的,就需要通过这个key来判断。如果是发给三四楼的,就会拿出消息通知给三四楼。所以这里还有个map方法,拿到通知的数据。
接下来我们看看它的应用,我把这个类改一下,让他通俗易懂。
import { Injectable } from '@angular/core'; import { Observable , Subject } from 'rxjs'; @Injectable() export class MessageService { private subject = new Subject<any>(); sendMessage(message: { type: string, data: any }) { this.subject.next({ text: message }); } clearMessage() { this.subject.next(); } getMessage(): Observable<{ type: string, data: any }> { return this.subject.asObservable(); } }
一目了然,一个sendMessage,一个getMessage。
在页面应用,我们需要引入Subscription类。这个类可以实现消息订阅,取消订阅,对于我们来说刚好订阅广播出的消息。由于涉及真实项目,只贴出部分代码。
import { Subscription } from 'rxjs'; @Component({ selector: 'website-category', templateUrl: 'websitecategory.component.html' }) export class WebsiteCategoryComponent implements AfterViewInit, OnDestroy { constructor( private messageService: MessageService) { this.subscription = this.messageService.getMessage() .subscribe((message: any) => { if (message.text.type == 'ItemBaseInfoRefresh') { this.initWebsiteCategory(message.text.data); } }); } subscription: Subscription;
上面的是接收的页面,首先会判断发送的消息是不是给自己的,如果是自己的就做自己的事情。
其实另一个发送页面只是负责发送消息。
this.messageService.sendMessage({ type: 'ItemBaseInfoRefresh', data: null });
那么其实大家就想问怎么接收到的消息。其实这里两个组件构造函数中注入的messageService是一个对象。因此接收页面去subscrible订阅的还是messageService的消息。ok,其实实现就是这么简单。
最后我不得不说一下我对subject的理解,这个东西是一种可以允许多订阅的Observable,对于每一个订阅者,Subject都会将其维护在自己的Observer列表中。因此在我们的项目中,有好几个页面都是订阅这个subject。那么如果Component卸载后订阅怎么清除呢,很简单,看下面。
ngOnDestroy() { this.subscription.unsubscribe(); }
OK,关于通知就说这么多,就是利用Subject的多路订阅通知实现观察者模式。
网上也有比较详细的解释:https://segmentfault.com/a/1190000005069851
上一篇 Angular中pipe的使用