文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Angular与Component store使用实例分析

2023-07-05 04:21

关注

这篇“Angular与Component store使用实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Angular与Component store使用实例分析”文章吧。

正文

我们知道,Angular 中因为有 servicerxjs 的存在,使得状态管理在 Angular,并非必须。

一个 BehaviorSubject 就形成了最简单的状态管理:

将逻辑部分分离到 service

使用 Rxjs 将 service 中的逻辑部分,拆分为状态和方法。Component subscribe state 来更新 view, 调用方法来修改 state。

Angular与Component store使用实例分析

我们知道,Angular 中可以使用 NgRx 提供的 store 来做状态管理。NgRx store 跟 Redux 本质上是一样的。多数时候,可能我们都觉得 Redux 太重了。而且强行将数据与 view 分离。

除了 ngrx store, ngrx 还提供了另外一种轻量级的状态管理,component store。本质上它跟我们刚刚介绍的状态管理模式是一致的,只是提供了一些接口方便我们使用。 NgRx - @ngrx/component-store

Angular与Component store使用实例分析

在定位上,可以参考 hooks 与 redux 的区分,Ngrx store 用来处理全局状态,Component Store 用来 component 内局部的状态管理使用。(Store 和 Component 拥有相同的生命周期)。当然,实际上使用下来,component store 也完全可以用来当作全局的状态管理来处理。

 component store 的使用方法

Angular与Component store使用实例分析

我们可以看到,store 主要提供了三个方法:

我们可以看出来,这样的接口设计跟 Mobx 或者 Vuex 是比较接近的。区别就是,因为 RxJS 的缘故,它的实现异常简单。几乎只是基于 behaviorSubject 包了一层壳。

有两点还是值得一提的:

updater 和 effect 的方法参数可以同时接受 value 和 observable value, 这使得我们在操作一个 stream 的时候,可以直接将 stream 作为参数。

比如我们现在有一个方法 updateUserName: (string | Observable<strring>) => void;

使用的时候,我们可以直接调用:updateUserName('zhangsan')

有时候我们在 component 里拿到的是一个 stream。

比如 form.valueChanges, 这时候我们就不需要手动 subscribe stream, 而是直接

updateUserName(form.valueChanges.pipe(map(form => form.userName)))

在 component 中使用

在 component 中使用也比较简单:

@Component({  template: `...`,  // ❗️MoviesStore is provided higher up the component tree})export class MovieComponent {  movie$: Observable<Movie>;  @Input()  set movieId(value: string) {    // calls effect with value. ???? Notice it's a single string value.    this.moviesStore.getMovie(value);    this.movie$ = this.moviesStore.selectMovie(value);  }  constructor(private readonly moviesStore: MoviesStore) {}}

当然,我们也可以做一点优化,比如,尽可能将逻辑放在 store 中 componet 只做简单的调用。将数据之间的联动关系放在 store 的 constructor 中,component 只做调用。

@Component({  template: `...`,  // ❗️MoviesStore is provided higher up the component tree})export class MovieComponent {  movie$: Observable<Movie>;  @Input()  set movieId(value: string) {    this.mobiesStore.patchState({movieId: value});  }  constructor(private readonly moviesStore: MoviesStore) {}}
@Injectable()export class MoviesStore extends ComponentStore<MoviesState> {  constructor(private readonly moviesService: MoviesService) {    super({movieId: string; movies: []});    this.geMovie(this.movieId$);  }  movieId$ = this.select(state => state.movieId);  movie$ = this.moviesStore.selectMovie(this.movieId$);  readonly getMovie = this.effect((movieId$: Observable<string>) => {    //....  });  readonly addMovie = this.updater((state, movie: Movie) => ({    // ...  }));  selectMovie(movieId: string) {     // ...  }}

因为这里的 component store 是针对单个 component 的,也就是通常情况它的使用场景是逻辑较为复杂的 component。一个 component 基于 input 的变化完全可以转化为对于 store 的监听。那么,我们基本上可以将 component 的多数 input 同步到 store 中。

在一段时间的使用过程中,我发现,这是比较费劲的,

比如 userName 这个字段原来:@Input userName: string;与 store 同步:@Inputset userName(val: string) {  this.store.patchState({userName: val});}如果想在 component 中直接调用 userName 就更麻烦了。private _userName: string;@Inputset userName(val: string) {  this._userName = val;  this.store.patchState({userName: val});}get userName() {  return this._userName;}

如果字段比较多,简直就是灾难。

最近在尝试一种不同于官网推荐的方法。我们知道,除了 set 我们还有一种更为常规的方法获取 input changes, 那就是 ngChanges。

export function mapPropChangesToStore<T extends JsonRecord>(this: ComponentStore<T>, mappedKeys: readonly string[], changes: SimpleChanges) {  const state = mappedKeys.reduce((prev: Partial<T>, propKey) => {    // eslint-disable-next-line @typescript-eslint/ban-ts-comment    // @ts-ignore    const propValue = changes?.[propKey];    if (!propValue) {      return prev;    }    return ({      ...prev,      [propKey]: propValue.currentValue,    });  }, {});  if (isEmpty(state)) {    return;  }  this.patchState(state);}

在 component 中对于 store 的使用

import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';import { mapPropChangesToStore } from '@dashes/ngx-shared';import { componentInputs, CsDemoStore } from './cs-demo.store';@Component({  selector: 'app-cs-demo',  templateUrl: './cs-demo.component.html',  styleUrls: ['./cs-demo.component.css']})export class CsDemoComponent implements OnChanges {  @Input() p1!: string;  @Input() p2!: string;  @Input() p3!: string;  constructor(public store: CsDemoStore) { }  ngOnChanges(changes: SimpleChanges): void {    mapPropChangesToStore.bind(this.store)(componentInputs, changes);  }}export const componentInputs = ['p1', 'p2'] as const;export type State = Pick&lt;CsDemoComponent, typeof componentInputs[number]&gt;;

以上就是关于“Angular与Component store使用实例分析”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯