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