Angular实现类似vuex状态管理功能、全局数据管理与同步更新

摘要:
使用该语言自定义数据的状态管理。如果有错误,请改正。首先,介绍rxjs中的主题;主题数据的订阅和分发,结合报纸和期刊的出版和订阅,模拟功能。主体既是可观察对象,也是观察对象。当后期没有数据更新时,主题对添加的订阅者不太友好,因为订阅者不会收到来自“rxjs”常量$=interval的返回值import{subject}。没有新数据的管道;constsubject=newSubject();constobserverA={next:value=˃console.log,error:error=˃console.log,complete:()=˃console.log('ObserverAcomplete!'),};主题订阅;//添加观察员A//international$。subscribe//订阅interval$object主题。下一个主题下一个主题下一个setTimeout;从'rxjs'导入{AsyncSubject};//主题完成后,AsyncSubject将返回值constsubject=newAsyncSubject();constobserverA={next:value=˃console.log,error:error=˃consol.log,complete:()=˃console.log('ObserverAcomplete!

自定义实现angular中数据的状态管理,如有不妥请指正

一、先介绍一下rxjs中subject;

Subject 数据的订阅与分发,结合报刊的发布与订阅进行功能的模拟,subject即是observeable对象也是observer对象,
subject对于后期没有数据更新时所添加的订阅者是不怎么友好的,因为不跟新数据时订阅者就不在收到返回的数值

    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广播模式

二、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,
  ) {}
...
 
this.http.get(xxx).subscribe(res => {
        if (res.code !== 200) {
          this.msg.error(res.message);
          return;
        }
  this.someSharedService$.settingKey('dataCount1', 'dataSum');
})

当完成数据请求、更新后,修改广播中心的数据,之后同步给接收者一份最新的数据,从而达到广播的的效果;

免责声明:文章转载自《Angular实现类似vuex状态管理功能、全局数据管理与同步更新》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇简单大根堆的实现Ubuntu12.04 安装Samba下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Vue|退出功能

一、前言 在我们进行web开发时,有一个很常规的功能退出登录,那么vue是怎么实现的呢 二、具体步骤   1、在index组件中,添加退出登录按钮,并且点击事件绑定一个退出方法   2、查看后端开发的接口文档,在用户模块里面,封装退出方法   3、在index的组件中,方法区域中调用退出登录   4、效果 三、总结 先找到对应的模块,定义好退出登录...

ant-design-vue 之form表单中label-col和wrapper-col使用

ant-design-vue 之form表单中label-col和wrapper-col使用 主要代码: :label-col="{ span: 5 }" :wrapper-col="{ span: 15 }" demo: <template> <div> <a-form :form="form" &g...

c# zxing生成二维码和打印

生成二维码代码 asset=“要生成的字符串”; public static Bitmap CreateQRCode(string asset) { EncodingOptions options = new QrCodeEncodingOptions { DisableECI = true,...

vue 后台 权限管理 三级渲染列表

下面的页面进行三级页面列表渲染 使用了el中的Layout布局 每一行占24个格     <!-- 角色列表区域 --> <el-table :data="rolelist" border stripe> <!-- 展开列 --> <el-table-column typ...

VUE 网页端改成桌面端(Electron)

展示效果    1、安装vue-cli   前提安装:http://nodejs.cn/download/   npm install -g @vue /cli  // 安装   vue --version  // 查询版本 2、创建项目   vue create 项目名 3、安装成功后执行   vue add electron-builder 4、运行...

vue.js中 ,回车键实现登录或者提交表单!

vue的功能非常强大,但是我们作为一个后端开发人员,前端的东西不一定都弄的很明白,今天就给大家介绍一个回车提交表单的真实案例,达到回车登录的效果! @keyup.enter实现的效果 <input v-model = "password"type="password"name=""class="pwd"placeholder="密码"@keyup.e...