Я пытаюсь создать библиотеку с функцией состояния и комбинированным редуктором.
Мой редуктор функций выглядит так:
index.ts
export const storageFeatureKey = 'storage';
export interface StorageState {
[fromBookEntries.bookEntriesFeatureKey]: fromBookEntries.State
}
export function reducers(state: StorageState | undefined, action: Action) {
return combineReducers({
[fromBookEntries.bookEntriesFeatureKey]: fromBookEntries.reducer
})(state, action);
}
bookEntriesFeatures выглядит так:
book-entries.reducer.ts
export const bookEntriesFeatureKey = 'book-entries';
export interface State extends EntityState<WarehouseBookEntry> {
selectedEntryId: number;
}
export const adapter: EntityAdapter<WarehouseBookEntry> = createEntityAdapter<WarehouseBookEntry>({
selectId: (entry) => entry.id
});
export const initialState: State = adapter.getInitialState({
selectedEntryId: null
});
export const reducer = createReducer(
initialState,
on(...),
on(...)
);
export const getSelectedEntryId = (state: State) => state.selectedEntryId;
const {
selectIds,
selectEntities,
selectAll,
selectTotal
} = adapter.getSelectors();
export const getBookEntriesIds = selectIds;
export const getBookEntriesEntities = selectEntities;
export const getAllBookEntries = selectAll;
export const getTotalBookEntries = selectTotal;
В моем функциональном модуле я импортирую StoreModule.forFeature () с моим функциональным ключом и редуктором функций.
Нет, я пытаюсь выбрать запись на основе выбранного идентификатора. Поэтому я запускаю действие, которое успешно добавляет идентификатор выбранной записи в состояние моих записей в книге.
Чтобы выбрать выбранную запись, у меня есть следующий селектор внутри моих селекторов функций:
index.ts
export const selectSelectedBookEntry = createSelector(
fromBookEntries.getBookEntriesEntities, // fromBookEntries is in my bookEntriesFeature
selectSelectedBookEntryId, // simply returns the selected id
(entries, selectedId) => {
//console.log(entries, selectedId)
//console.log("fired");
return entries && entries[selectedId];
}
);
При загрузке записей через другое отправленное действие селектор вызывается только один раз (перед загрузкой данных). Я обнаружил, что когда я создаю селекторы из моего bookEntriesAdapter внутри своих селекторов функций, это работает. Нравится:
index.ts
export const selectStorageState = createFeatureSelector<StorageState>(
storageFeatureKey
);
export const selectBookEntriesState = createSelector(
selectStorageState,
state => state[fromBookEntries.bookEntriesFeatureKey]
);
const {
selectIds,
selectEntities: selectBookEntriesEntities,
selectAll,
selectTotal
} = fromBookEntries.adapter.getSelectors(selectBookEntriesState);
export const selectAllBookEntries = createSelector(
selectBookEntriesState,
selectAll
)
export const selectSelectedBookEntry = createSelector(
selectBookEntriesEntities,
selectSelectedBookEntryId,
(entries, selectedId) => {
//console.log(entries, selectedId)
//console.log("fired");
return entries && entries[selectedId];
}
);
Но почему? Я немного потерялся, пытаясь понять, почему это не работает наоборот.
Приведенный выше пример, который не работает, взят из официального документа ngrx (https://ngrx.io/guide/entity/adapter). Тот, который работает, взят из примера кода ngrx / platform (https://github.com/ngrx/platform/blob/master/projects/example-app/src/app/books/reducers/index.ts).
Я не думаю, что это необходимо, но я не расширяю состояние root-app-store, поскольку у меня нет доступа к нему, потому что это библиотека (пытаясь обойти дизайн, управляемый доменом, и я создал feature-lib для решения такого рода проблем). Или это может быть проблема?
Я был бы признателен, если бы кто-нибудь мог объяснить это немного подробнее.