Angular實現相似vuex狀態管理功能、全局數據管理與同步更新

自定義實現angular中數據的狀態管理,若有不妥請指正javascript

1、先介紹一下rxjs中subject;vue

Subject 數據的訂閱與分發,結合報刊的發佈與訂閱進行功能的模擬,subject便是observeable對象也是observer對象,
subject對於後期沒有數據更新時所添加的訂閱者是不怎麼友好的,由於不跟新數據時訂閱者就不在收到返回的數值java

    import {subject}from’rxjs’
    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實現相似vuex的全局數據管理就須要用到 BehaviorSubject廣播模式vuex

2、angular服務文件app

在app.module.ts中註冊服務文件ide

import { SomeSharedService } from '@shared/window-service/window.service';
providers: [
    ...
    SomeSharedService,
  ],

 

TS文件:this

service.module.ts文件spa

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服務文件名:code

window.service.ts文件server

import { 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);
  }
}

 

3、全局數據初始化

在全局公用組件中進行全局數據的初始化,具體怎麼用看本身怎麼考慮,頁面刷新時數據都會從新向後臺拿取數據;

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$.globalVar.next(res.data); 從全局服務SomeSharedService文件中分發文件;

4、訂閱服務數據

在須要的頁面訂閱分發內容,且會保存最後一次的數據;

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();
       }
     });
// 由於有一些數據渲染的問題 因此須要加一層判斷,這就基本實現了從後臺拿取數據,在多個頁面進行展現;

5、實現數據修改及同步更新

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');
})

當完成數據請求、更新後,修改廣播中心的數據,以後同步給接收者一份最新的數據,從而達到廣播的的效果;

相關文章
相關標籤/搜索