web-dev-qa-db-ja.com

ngrxストアからIDでアイテムを選択するセレクターを作成する方法

セレクターについてngrxストアの documentation を読み、アイテムIDで1つのアイテムを選択するためにセレクターを作成する方法を理解する必要があります。 selectAllItemsセレクターからすべてのアイテムを取得するときに、ストアサブスクリプションの一部としてこれを既に実行できますが、ストア内のアイテムのリストから特定のアイテムを選択する方法を理解する必要があります。私の主な理由は、createSelectorが私が恩恵を受けたいパフォーマンスの向上を提供することです。

ここに私のコードがあります:

import { AppState, Item } from '../../shared/models/index';
import { createSelector } from '@ngrx/store';

export const selectItems = (state: AppState) => state.eventsState;

export const selectAllItems = createSelector(selectItems, (allItems: { items: Item[] }) => {
  if (allItems && allItems.items) {
   return allItems.items.filter((item: Item) => (!item.active && !item.closed));
  } else {
    return allItems.items;
  }
});

次に、コントローラーでIDでフィルターして必要なアイテムを取得します。

this.store.select(selectors.selectAllItems)
  .filter(data => data !== null)
  .subscribe(allItems => {
    this.item = allItems.filter(item => {
      return item.id === this.navParams.data.id;
    });
  });

特定のアイテムのセレクターを作成し、次のように使用できるようにしたいと思います。

this.store.select(selectors.selectItemById(this.navParams.data.id))
  .filter(data => data !== null)
  .subscribe(selectedItem => {
    this.item = selectedItem;
  });

任意の助けをいただければ幸いです。

10

いくつかの研究の後、私は自分の問題を解決しました。ファクトリ関数を使用して、必要なselectItemByIdセレクターを取得しました。これが私の新しいセレクターです。

import { AppState, Item } from '../../shared/models/index';
import { createSelector } from '@ngrx/store';

export const selectItems = (state: AppState) => state.eventsState.items;

export const getItemById = (id) => createSelector(selectItems, (allItems) => {
  if (allItems) {
    return allItems.find(item => {
      return item.itemId === id;
    });
  } else {
    return {};
  }
});

その後、コントローラーで行う必要があるのは、このセレクターを呼び出して、ストアからアイテムを取得するために必要なアイテムのIDを渡すことだけです。

import * as selectors from '../../app/store/selectors';

this.store.select(selectors.getItemById(id))
  .subscribe((item) => {
    this.item = item;
  });
20

エンティティを使用すると、すべてがはるかに簡単になります。それらをオブジェクトとして保存する場合、キーはアイテムのidで、値はアイテム自体です。アイテムを配列として保持する方法は2つあります-アイテムのIDまたは完全なオブジェクトのみを保存します。

減速機内:

export interface ItemsState {
  loaded: boolean;
  loading: boolean;
  items: { [key: string]: Item };
  itemIds: any[];
}

const initialState: ItemsState = {
  loaded: true,
  loading: false,
  items: {
    0: {
      foo: 'bar'
    },
    1: {
      bar: 'foo'
    }
  },
  itemIds: [0, 1]
}

セレクター内:

export const getItems = (state: ItemsState) => state.items;

export const getItemById = (id) => createSelector(
  getItems, 
  (items) => items[id]
);

コンテナ内(コンポーネント):

constructor(
  private store: Store,
  private route: ActivatedRoute
) {}

getItemOnInit(): void {
  // or any other way to retrieve id from route
  const id = this.route.snapshot.params.id;
  this.store.pipe(select(getItemById(id)));
}
8

ストアで利用可能なデータに基づいて:

export const selectUser = (state: AppState) => state.selectedUser;
export const selectAllBooks = (state: AppState) => state.allBooks;

export const selectVisibleBooks = createSelector(
  selectUser,
  selectAllBooks,
  (selectedUser: User, allBooks: Books[]) => {
    if (selectedUser && allBooks) {
      return allBooks.filter((book: Book) => book.userId === selectedUser.id);
    } else {
          return allBooks;
    }
   }
);

ストアで利用できないデータ:

ストアで使用できないデータに基づいて状態の一部を選択するには、セレクター関数にpropsを渡すことができます。これらの小道具は、すべてのセレクターとプロジェクター機能を通過します。そのためには、コンポーネント内でセレクターを使用するときにこれらの小道具を指定する必要があります。

たとえば、カウンターがあり、その値を乗算する場合、乗算係数を小道具として追加できます。

セレクターまたはプロジェクターの最後の引数はprops引数です。この例では、次のようになります。

export const getCount = createSelector(
  getCounterValue,
  (counter, props) => counter * props.multiply
);

コンポーネント内で、小道具を定義できます。

ngOnInit() {
  this.counter = this.store.pipe(select(fromRoot.getCount, { multiply: 2 }))
}

彼女は ドキュメント です。

1
Rahmathullah M