LoginSignup
0
0

[Angular]NgRxで複数Storeを作った時に、Selectorで跨いでfilterとかして取得したい時

Posted at

いやー、毎日更新しようかなと思ったけど、ネタがなくなって更新止まった瞬間に一気にやる気がなくなったわー

こんな状況の時のサンプル

  • 1システム(アプリ)内でNgRxでデータを管理する
  • アプリ共通のStoreと画面や機能単位で管理するStoreがあり、Storeが複数ある
    ※Action・Reducer・Selectorも複数ある
  • 機能Selectorで共通Storeの値を参照して、なんか値を返したい

サンプルソース

サンプルフォルダ構成

store
|-app-state.ts
|-app-selector.ts
|-sample-state.ts
|-sample-selector.ts

アプリ共通のStateとSelector

app-state.ts
export const featureName = 'appState';
export interface State {
  isAdmin: boolean;
}
app-selector.ts
import {featureName, State} from './app-state'

// app-storeのStateの値を全部参照できるSelector
const featureSelector = createFeatureSelector<State>(featureName);

// isAdminだけ参照するためのSelector
export const isAdmin = createSelector(
  featureSelector,
  (state) => state.isAdmin
);

機能のStateとSelector

sample-state.ts
export const featureName = 'sampleState';
export interface State {
  // 管理者向けメッセージ
  adminMessage: string;
  // 一般ユーザ向けメッセージ
  userMessage: string;
}
sample-selector.ts
import {featureName, State} from './sample-state'

// app-selectorで定義されていて、このファイル内で参照したいSelector
import {isAdmin} from './app-selector'

// sample-storeのStateの値を全部参照できるSelector
const featureSelector = createFeatureSelector<State>(featureName);

// app-selectorのisAdminを条件に対象のメッセージを返す
export const message = createSelector(
  featureSelector, // ample-storeのStateの値全部
  isAdmin,         // app-selectorのisAdmin
  (state, isAdmin) => isAdmin ? state.adminMessage : state.userMessage
);

解説

単純なお話で、
sample-selector.tsにて、参照したいSelectorをimportして、
createSelectorの引数で指定してあげるだけ。
createSelectorの引数は別に対象機能のStateだけしか渡せないというわけではなく、
いくらでも別の機能のSelector経由のStateの値を指定することが出来るみたいです。

まとめ

まぁあまりにもあっちゃこっちゃで参照しあうのは、そもそも設計がよろしくないんじゃね?って感じがしますね。

またComponent側でmargeを使って、pipeを使ってwithLatestFromからそれぞれの値を取得してみたいなことも出来るのかなと思いますが、複雑になって読みづらく保守しずらくなるだけな気もするので、取ってくる段階で加工が出来るのであればComponent側では取って出すだけぐらいにした方がシンプルに作れるのかなって気がします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0