关于rxjs subject订阅分发实现Angular的全局数据管理与同步更新
自定义实现angular中数据的状态管理,如有不妥请指正 一、先介绍一下rxjs中subject; Import {subject}from’rxjs’ Subject 数据的订阅与分发,结合报刊的发布与订阅进行功能的模拟,subject即是observeable对象也是observer对象,subject对于后期没有数据更新时所添加的订阅者是不怎么友好的,因为不跟新数据时订阅者就不在收到返回的数值 ????const?interval$?=?interval(1000).pipe(take(10)); ????const?subject?=?new?Subject(); ????const?observerA?=?{ ??????next:?value?=>?console.log(‘Observer?A?get?value:?‘?+?value),??????error:?error?=>?console.log(‘Observer?A?error:?‘?+?error),??????complete:?()?=>?console.log(‘Observer?A?complete!‘),????}; ????const?observerB?=?{ ??????next:?value?=>?console.log(‘Observer?B?get?value:?‘?+?value),??????error:?error?=>?console.log(‘Observer?B?error:?‘?+?error),??????complete:?()?=>?console.log(‘Observer?B?complete!‘),????}; ????subject.subscribe(observerA);?//?添加观察者A ????interval$.subscribe(subject);?//?订阅interval$对象 ????setTimeout(()?=>?{ ??????subject.subscribe(observerB);?//?添加观察者B ????},?1000); Import{BehaviorSubject}from’rxjs’; behaviorSubject 是subject的变种,最大的区别就是?behaviorSubject是用于保存最新的数值,而不是单纯的发送事件,会将最后一次发送的值作为当前值保存在内部属性中。 ????const?subject?=?new?BehaviorSubject(0); //BehaviorSubject小括号0代表的是状态 ????const?observerA?=?{ ??????next:?value?=>?console.log(‘Observer?A?get?value:?‘?+?value),????}; ????subject.subscribe(observerA);?//?添加观察者A ????//?interval$.subscribe(subject);?//?订阅interval$对象 ????subject.next(1); ????subject.next(2); ????subject.next(3); ????setTimeout(()?=>?{ ??????subject.subscribe(observerB);?//?添加观察者B ????},?1000); Import {ReplaySubject}from’rxjs’; ReplaySubject 用于重复发送最近几次的值给订阅者 ????const?subject?=?new?ReplaySubject(2); //ReplaySubject后的2为最后两次发送的数值 ????const?observerA?=?{ ??????next:?value?=>?console.log(‘Observer?A?get?value:?‘?+?value),?1000); Import{AsyncSubject}from’rxjs’; AsyncSubject他会在subject完成后才返回一个值 ????const?subject?=?new?AsyncSubject(); ????const?observerA?=?{ ??????next:?value?=>?console.log(‘Observer?A?get?value:?‘?+?value),????}; ????subject.subscribe(observerA);?//?添加观察者A ????//?interval$.subscribe(subject);?//?订阅interval$对象 ????subject.next(1); ????subject.next(2); ????subject.next(3); ????subject.complete(); ????setTimeout(()?=>?{ ??????subject.subscribe(observerB);?//?添加观察者B ????},?1000); 我们要实现angular的全局数据管理就需要用到 《BehaviorSubject》 二、angular服务文件 在app.module.ts中注册服务文件
import?{?
SomeSharedService?}?
from?
‘@shared/window-service/window.service‘;
providers:?[
????...
????
SomeSharedService,
??],
TS文件:service.module.ts import { NgModule,ModuleWithProviders } from ‘@angular/core‘; import { SomeSharedService } from ‘./window.service‘; export { SomeSharedService }; @NgModule() export class ServicesModule { static forRoot(): ModuleWithProviders { return { ngModule: ServicesModule,providers: [SomeSharedService],}; } } TS服务文件名:window.service.ts import { Injectable } from ‘@angular/core‘; import { BehaviorSubject } from ‘rxjs‘; @Injectable() export class SomeSharedService { public globalVar: BehaviorSubject<any> = new BehaviorSubject({ dataCount1: 0,dataCount2: 0, 三、全局数据初始化 在全局公用组件中进行全局数据的初始化,具体怎么用看自己怎么考虑,页面刷新时数据都会重新向后台拿取数据;
ngOnInit():?
void?{
????
const?
source?=?
timer(
0,?
30000);
????
const?
data?=?
source.
pipe(
??????
mergeMap(
val?
=>?{
????????
return?
this.
http.
get(
‘/admin‘);
??????}),
??????
distinctUntilChanged(),
????);
????
this.
distinctSub?=?
data.
subscribe(
res?
=>?{
??????
this.
someSharedService$.
globalVar.
next(
res.
data);
????});
??}
ngOnDestroy():?
void?{
????
this.
distinctSub.
unsubscribe();
??}
因为业务需要 定时向后台请求一次数据更新,所以简单写了一下 ,如果不需要就只要放一个http请求就行了; 使用??this.someSharedService$globalVarnext(resdata); 从全局服务SomeSharedService文件中分发文件; 四、订阅服务数据 在需要的页面订阅分发内容,且会保存最后一次的数据;
import?{?
SomeSharedService?}?
from?
‘@shared/window-service/window.service‘;
constructor(
?
private?
someSharedService$:?
SomeSharedService,
??)?{}
?
...
this.
someSharedService.
globalVar.
subscribe(
res?
=>?{
??????
if?(!(
this.
cdr?
as?
ViewRef).
destroyed)?{
????????
this.
item?=?
res;
????????
this.
cdr.
detectChanges();
??????}
????});
因为有一些数据渲染的问题 所以需要加一层判断,这就基本实现了从后台拿取数据,在多个页面进行展示; 五、实现数据修改及同步更新
constructor(
?
private?
someSharedService$:?
SomeSharedService,
??)?{}
?
...
.
subscribe(
res?
=>?{
????????
if?(
res.
code?!==?
200)?{
??????????
this.
msg.
error(
res.
message);
??????????
return;
????????}
this.
someSharedService$.
settingKey(
‘dataCount1‘,?
‘dataSum‘);
})
?
当完成数据请求后,调用我们内部方法,就可以在本地同步实现更新数据了; 其中原理将在后期有空时更新。 ? ? subject (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |