关于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),
      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.ts

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

三、全局数据初始化

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

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文件中分发文件;

四、订阅服务数据

在需要的页面订阅分发内容,且会保存最后一次的数据;

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,

) {}

...

.subscribe(res => {

if (res.code !== 200) {

this.msg.error(res.message);

return;

}

  this.someSharedService$.settingKey(‘dataCount1‘, ‘dataSum‘);

})

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

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

subject

原文地址:https://www.cnblogs.com/bomdeyada/p/11718943.html

时间: 2024-08-03 09:27:33

关于rxjs subject订阅分发实现Angular的全局数据管理与同步更新的相关文章

事件订阅分发模型

最近看了下各位大师写的事件订阅分发的模型很有感触,js果然强大到行如流水,下面这段模型摘自汤姆大叔的深入理解Javascript,非常感谢原作者 原文链接:http://www.sxrczx.com/docs/js/2305513.html function Event(name) { var handlers = []; this.getName = function () { return name; }; this.addHandler = function (handler) { han

Java使用RabbitMQ之订阅分发(Topic)

使用RabbitMQ进行消息发布和订阅,生产者将消息发送给转发器(exchange),转发器根据路由键匹配已绑定的消息队列并转发消息,主题模式支持路由键的通配. 生产者代码: 1 package org.study.exchange3.topic3; 2 3 import com.rabbitmq.client.Channel; 4 import com.rabbitmq.client.Connection; 5 import org.junit.Test; 6 import org.study

rxjs——subject和Observable的区别

一个 Observable 是可以被多个 observer 订阅的,只是每个订阅都是一个新的独立的 Observable execution : const { Observable } = Rx const clock$ = Observable.interval(1000).take(3); const observerA = { next(v) { console.log('A next: ' + v) } } const observerB = { next(v) { console.l

[RxJS] Subject: an Observable and Observer hybrid

This lesson teaches you how a Subject is simply a hybrid of Observable and Observer which can act as a bridge between the source Observable and multiple observers, effectively making it possible for multiple observers to share the same Observable exe

[RxJS] Subject basic

A Subject is a type that implements both Observer and Observable types. As an Observer, it can subscribe to Observables, and as an Observable it can produce values and have Observersw subscribe it. First time I read implements both Observer and Obser

拟物设计和Angular的实现 - Material Design (持续更新)

原文:拟物设计和Angular的实现 Material Design是Google最新发布的跨平台统一视觉设计语言.直接翻译是物质设计,但是我更倾向于使用"拟物设计"更为准确. 据谷歌介绍,Material Design基于"真实的触感,灵感源自对纸和墨水的研究," 能够让用户 "理解那些用于替代真实世界的可视线索,""而又不违背力学原理."另外,光线.表面和移动的基本原理是表现对象如何移动.交互和相互关联地存在于空间中的关键

angular 异步实时刷新页面,更新数据

$scope.$apply(function() { $scope.results.push(oo);//刷新的内容 }); ps: http://www.angularjs.cn/A0a6

angular - 导入全局样式

生产环境和浏览器环境都导入了. 原文地址:https://www.cnblogs.com/cisum/p/9123380.html

[RxJS] Reusable multicasting with Subject factories

The way we use publish() (or multicast with an RxJS Subject) makes the shared Observable not reusable if the shared execution happens to complete or emit an error. In this lesson we will see how to use a simple Subject factory function in order to cr