亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Angular與Component?store使用實例分析

發布時間:2023-02-20 10:15:33 來源:億速云 閱讀:152 作者:iii 欄目:開發技術

這篇“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 主要提供了三個方法:

  • select, 用來拆分 state

  • updater, 用來更新 state, 主要是無 effect 的 state 更新。

  • effect, 用來處理有 effect 的情況,調用 updater 的方法來更新數據。

我們可以看出來,這樣的接口設計跟 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)))

  • updater 和 effect 將 stream 作為參數后會自動 subscribe 并在 store 被銷毀的時候 unsubscribe, 這就意味著你不用再寫一堆手動 unsubscribe 的邏輯。

在 component 中使用

在 component 中使用也比較簡單:

  • 將 component 中必要的數據投喂給 store, 一般來說是 input.

  • 在 component 中調用 updater 或者 effect 返回的方法修改 state。

  • 在 component 中 subscribe state 實現 view 層的渲染。

@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 中。

在一段時間的使用過程中,我發現,這是比較費勁的,

  • 同一個字段,我需要在 component 和 store state 中聲明兩次。

  • Input 必須轉寫成 set 模式

比如 userName 這個字段
原來:
@Input userName: string;
與 store 同步:
@Input
set userName(val: string) {
  this.store.patchState({userName: val});
}
如果想在 component 中直接調用 userName 就更麻煩了。
private _userName: string;
@Input
set 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使用實例分析”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

绿春县| 封丘县| 正定县| 年辖:市辖区| 宾川县| 九龙坡区| 凤阳县| 临夏县| 许昌县| 永济市| 宿州市| 永福县| 洪雅县| 文昌市| 郓城县| 潍坊市| 蒙山县| 淅川县| 松阳县| 调兵山市| 三门县| 泊头市| 晋城| 普兰县| 宜宾县| 浙江省| 乌什县| 常宁市| 武宁县| 渭源县| 永清县| 长寿区| 金川县| 安平县| 铜鼓县| 东兴市| 雅江县| 开阳县| 安塞县| 汽车| 舒城县|