Итак, я нашел обходное решение, все еще используя NGRX.
Прежде чем начать, я просто хочу сказать, что ngrx также имеет пакет ngrx / data, который обеспечивает меньше шаблонов. Но пока я читал об этом, я нашел окончательный ответ на свой вопрос:
https://ngrx.io/guide/data/limitations "Эта библиотека мелкая -клонирует данные сущности в коллекциях. Он не клонирует сложные, вложенные или массивные свойства. Вам придется провести глубокие тесты на равенство и клонировать себя < / strong> перед тем, как запросить у NgRx Data сохранение данных. "
Я считаю, что это верно и для ngrx / entity.
Я начал искать альтернативные решения: BreezeJs, NGXS, Akita, из которых я быстро нашел только NGXS, понятный мне, но потребовавших усилий, чтобы отделить мою реализацию ngrx от проекта.
Итак, я вернулся к ngrx и попытался найти обходной путь для трехуровневых вложенных данных.
Создайте 3 отдельных состояния сущности (я попытаюсь использовать ngrx / data, которые могут точно уменьшить весь шаблон)
Создайте функцию, которая будет возвращать все необходимые сущности и идентификаторы для каждой сущности (используйте normalizr для нормализации)
export function normalizeTrainingArray(trainings: Training[]) {
var normalized = normalize(trainings, trainingsSchema);
var entities = {
trainings: {},
exercises: {},
sets: {}
}
entities.trainings = normalized.entities.trainings ? normalized.entities.trainings : {};
entities.exercises = normalized.entities.exercises ? normalized.entities.exercises : {};
entities.sets = normalized.entities.sets ? normalized.entities.sets : {};
var ids = {
trainingIds: [],
exerciseIds: [],
setIds: []
}
ids.trainingIds = normalized.entities.trainings ? Object.values(normalized.entities.trainings).map(x => x.id) : [];
ids.exerciseIds = normalized.entities.exercises ? Object.values(normalized.entities.exercises).map(x => x.id) : [];
ids.setIds = normalized.entities.sets ? Object.values(normalized.entities.sets).map(x => x.id) : [];
return {
entities,
ids
}
Что-то вроде этого будет достаточно. Отправьте действие normalizeData и используйте эффект для вызова этого метода и отправьте 3 различных действия для fetchedData ...
Что-то вроде:
trainingsNormalized$ = createEffect(() =>
this.actions$.pipe(
ofType(TrainingActions.normalizeTrainings),
tap(payload => {
var normalized = normalizeTrainingArray(payload.trainings);
this.store.dispatch(TrainingActions.trainingsFetched({ entities: normalized.entities.trainings, ids: normalized.ids.trainingIds }))
this.store.dispatch(ExerciseActions.exercisesFetched({ entities: normalized.entities.exercises, ids: normalized.ids.exerciseIds }))
this.store.dispatch(SetActions.setsFetched({ entities: normalized.entities.sets, ids: normalized.ids.setIds }))
})
)
, { dispatch: false });
И в одном образце редуктора:
// GET ALL
on(TrainingActions.trainingsFetched, (state: TrainingState, payload: { entities: Dictionary<Training>, ids: string[] }) => {
return {
...state,
entities: payload.entities,
ids: payload.ids
}
}),
Результат:
![результат](https://i.imgur.com/S9qgMsX.png)
person
maran
schedule
14.09.2019