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),       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$对象     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),       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$对象     subject.next(1);     subject.next(2);     subject.next(3);     setTimeout(() => {       subject.subscribe(observerB); // 添加观察者B     }, 1000); Import{AsyncSubject}from’rxjs’; AsyncSubject他会在subject完成后才返回一个值     const subject = new AsyncSubject();     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$对象     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.tsimport { Injectable } from '@angular/core';

import { BehaviorSubject } from 'rxjs';
@Injectable()
export class SomeSharedService {
  public globalVar: BehaviorSubject<any> = new BehaviorSubject({
    dataCount1: 0,
    dataCount2: 0,
dataCount3: 0,
dataSum: 0,
}); settingKey(key, sumKey) { const globalVar = this.globalVar.getValue(); globalVar[key] -= 1; globalVar[sumKey] -= 1; this.globalVar.next(globalVar); } }

三、全局数据初始化

在全局公用组件中进行全局数据的初始化,具体怎么用看自己怎么考虑,页面刷新时数据都会重新向后台拿取数据;

ngOnInit():  void {
 
     const  source =  timer( 030000);
       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$.globalVar.next(res.data); 从全局服务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();
 
      }
 
    });
 

因为有一些数据渲染的问题 所以需要加一层判断,这就基本实现了从后台拿取数据,在多个页面进行展示;

五、实现数据修改及同步更新

import {  SomeSharedService }  from  '@shared/window-service/window.service';
constructor(
    private  someSharedService$SomeSharedService,
  ) {}
 
 
...
 
this.http.get(xxx). subscribe( res  => {
 
         if ( res. code !==  200) {
           this. msg. error( res. message);
           return;
        }
 
  this. someSharedService$. settingKey( 'dataCount1''dataSum');
 
})
 

当完成数据请求后,调用我们内部方法,就可以在本地同步实现更新数据了;

其中原理将在后期有空时更新。

 

 

subject


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM