Как объединить редукторы, когда одному из них нужны реквизиты?
У меня есть следующая модель:
interface Device {
id: string;
data: IDeviceData;
}
и DeviceReducer, который выглядит следующим образом:
import { EntityState, EntityAdapter, createEntityAdapter } from '@ngrx/entity';
import { Device } from '../model/device';
import { SubnetBrowserApiActions } from 'src/app/explorer/actions';
export interface State extends EntityState<Device> { }
export const adapter: EntityAdapter<Device> = createEntityAdapter<Device>();
export const initialState: State = adapter.getInitialState();
export function reducer(
state = initialState,
action:
| SubnetBrowserApiActions.SubnetBrowserApiActionsUnion
): State {
switch (action.type) {
case SubnetBrowserApiActions.SubnetBrowserApiActionTypes.LoadEntriesSucces: {
return adapter.upsertMany(action.payload.entries, state);
}
default: {
return state;
}
}
}
const {
selectAll,
} = adapter.getSelectors();
export const getAllDevices = selectAll;
В моем другом редукторе, когда я хочу выбрать устройства, используя массив идентификаторов, я использую этот код:
export const getVisibleDrives = createSelector(
[fromRoot.getAllDevices, getVisibleDrivesSerialNumbers],
(devices, visibleDevicesIds) =>
devices.filter((device) => onlineDevicesIds.includes(device.serialNumber)),
);
Этот код очень повторяется, поэтому я хотел бы добавить параметр параметризованного селектора, который будетвернуть только те диски, которые имеют идентификатор в массиве, который я передаю как проп.То, что я пытался сделать, выглядит следующим образом:
Дополнительный селектор в DeviceReduced
export const getDrivesWithIds = (ids: string[]) => createSelector(
getAllDevices,
devices => devices.filter(device => ids.includes(device.id))
);
И затем объедините их в , следуя способом:
export const getVisibleDrives = createSelector(
getVisibleDrivesSerialNumbers,
(ids) => fromRoot.getDrivesWithIds
);
Проблема здесь в том, что возвращаемый тип этого селектора равен
(ids: string[]) => MemoizedSelector<State, Device[]>
Что делает невозможным для меня что-либо полезное с этим селектором.В качестве примера я хотел бы отфильтровать этот список по ключевому слову, и я не могу использовать метод filter
для него:
Пример использования
export const getFilteredVisibleDrives = createSelector(
[getVisibleDrives, getKeywordFilterValue],
(visibleDrives, keywordFilter) => {
return visibleDrives
.filter(drive => // in this line there is an error: Property 'filter' does not exist on type '(ids: string[]) => MemoizedSelector<State, Device[]>'
drive.ipAddress.toLowerCase().includes(keywordFilter.toLowerCase()) ||
drive.type.toLowerCase().includes(keywordFilter.toLowerCase()) ||
drive.userText.toLowerCase().includes(keywordFilter.toLowerCase())
);
},
);