从ngrx/store中提取特定数据

cro*_*sey 2 rxjs ngrx angular

所以我已经多次阅读过这篇文章,但是现在定义的设置和示例与商店示例应用程序中显示的方法不同.

我已经编写了大量基于示例应用程序的商店代码,因此如果我们继续使用示例应用程序在此帖子中进行参考:

书籍减速机:

export interface State {
  ids: string[];
  entities: { [id: string]: Book };
  selectedBookId: string | null;
};

const initialState: State = {
  ids: [],
  entities: {},
  selectedBookId: null,
};

export function reducer(state = initialState, action: book.Actions | collection.Actions): State {
  switch (action.type) {
    case book.ActionTypes.SEARCH_COMPLETE:
    case collection.ActionTypes.LOAD_SUCCESS: {
      const books = action.payload;
      const newBooks = books.filter(book => !state.entities[book.id]);

      const newBookIds = newBooks.map(book => book.id);
      const newBookEntities = newBooks.reduce((entities: { [id: string]: Book }, book: Book) => {
        return Object.assign(entities, {
          [book.id]: book
        });
      }, {});

      return {
        ids: [ ...state.ids, ...newBookIds ],
        entities: Object.assign({}, state.entities, newBookEntities),
        selectedBookId: state.selectedBookId
      };
    }

export const getEntities = (state: State) => state.entities;
export const getIds = (state: State) => state.ids;
Run Code Online (Sandbox Code Playgroud)

Reducers index.ts(缩短但保留相关信息):

import { createSelector } from 'reselect';
import { compose } from '@ngrx/core/compose';
import { storeFreeze } from 'ngrx-store-freeze';
import { combineReducers } from '@ngrx/store';
import * as fromBooks from './books';


export interface State {
  books: fromBooks.State;
}

const reducers = {
  books: fromBooks.reducer,
};

const productionReducer: ActionReducer<State> = combineReducers(reducers);
export function reducer(state: any, action: any) {
    return productionReducer(state, action);

}

export const getBooksState = (state: State) => state.books;
export const getBookEntities = createSelector(getBooksState, fromBooks.getEntities);
export const getBookIds = createSelector(getBooksState, fromBooks.getIds);
Run Code Online (Sandbox Code Playgroud)

现在我无法理解的是如何构建"查询",我希望能够做的是将ID"456"传递给一个函数,该函数将从ID为"456"的书中查看State内部.将此数据返回到Book的可观察对象,以便我可以在我的模板/组件中使用它.

我已经看了几个小时的示例代码,当我认为我已经掌握了它时,我无法弄清楚我做错了什么.如果有人能够解释如何构建一个采用自定义参数的选择器.

我已经使用了示例应用程序中的确切代码,希望如果找到答案,那将对未来的读者有所帮助.

Vic*_*doy 7

当您使用redux模式时,您必须通过Actions执行所有操作.

首先,您需要在商店中存储选定的ID,在这种情况下,"selectedBookId"属性作为新的Action,如SELECTED_BOOK

第二步,要获得所选书籍,您需要创建一个选择器,将选定的BookId与您的实体数组相结合,如:

export const getSelected = createSelector(
  getEntities,
  getSelectedId,
  (entities , selectedId) => entities.find(entities => entities.id === selectedId)
);
Run Code Online (Sandbox Code Playgroud)

index.ts

export const getSelectedBook = createSelector(getBookState, fromBook.getSelected);
Run Code Online (Sandbox Code Playgroud)

最后要获取book对象,需要调用选择器

this.book$ = this.store.select(fromRoot.getSelectedBook);
Run Code Online (Sandbox Code Playgroud)