Я использую ngrx/store и Angular 6. У меня в магазине глубокая вложенная структура. Но я чувствую, что это неправильный способ держать это так:
const state = [
{
aliases: ['alias1', 'alias2'],
isRequired: false,
isSensitive: false,
name: 'Adress',
timezoneId: 'UTC',
children: []
},
{
aliases: ['alias3', 'alias4'],
isRequired: true,
isSensitive: false,
name: 'Phone',
timezoneId: 'UTC-5',
children: [
{
aliases: ['alias1', 'alias2'],
isRequired: true,
isSensitive: false,
name: 'Sub-Phone',
timezoneId: 'UTC-5',
children: [
{
aliases: ['alias-phone1', 'alias-phone2'],
isRequired: false,
isSensitive: true,
name: 'Sub-Sub-Phone',
timezoneId: 'UTC',
children: []
}
]
}
]
}
]
Здесь свойство name похоже на id, оно не может быть таким же на том же уровне, но может быть у дочерних элементов. Например, Sub-Phone и Sub-Sub-Phone могут называться Phone. Как лучше всего сохранить в магазине такую конструкцию, которую можно будет легко изменить. Потому что теперь, если я хочу изменить name: 'Phone', я должен полностью вернуть этот объект со всеми его дочерними элементами.
Как я могу это нормализовать?





Если у вас есть доступ к реализации сервера, нормализация может быть выполнена непосредственно там. Однако более вероятно, что вы собираетесь нормализовать состояние в клиенте, используя стороннюю библиотеку, например, normalizr.
Есть несколько статей, обсуждающих эту тему, например этот на Hackernoon.
Обычный шаблон - следовать это руководство, чтобы нормализовать форму состояния. Не гнездитесь. Создайте идентификатор, в котором хранятся объекты. А затем создайте идентификатор, в котором хранятся отношения (в вашем сценарии дети). Я создал для вас образец состояния
const state = {
objects: {
id: ['Address', 'Phone', 'Sub-Phone', 'Sub-Sub-Phone'],
entities: {
'Address': {
isRequired: false,
isSensitive: false,
timezoneId: 'UTC'
},
'Phone': {
isRequired: true,
isSensitive: false,
timezoneId: 'UTC-5'
},
'Sub-Phone': {
isRequired: true,
isSensitive: false,
timezoneId: 'UTC-5',
},
'Sub-Sub-Phone': {
isRequired: false,
isSensitive: true,
timezoneId: 'UTC',
}
}
},
children: {
'Address': [],
'Phone': ['Sub-Phone'],
'Sub-Phone': ['Sub-Sub-Phone']
}
}
Обратите внимание, что состояние имеет 2 уровня: один для объектов, второй для детей. objects хранит идентификаторы и сущности. Потомки хранят по одному массиву для каждого ключа объекта с его дочерними элементами. Обратите внимание, что в ny примере в массивах есть только один дочерний элемент, но у вас может быть что-то вроде
'Phone': '['Sub-Phone', 'Sub-Phone2', 'Sub-Phone3']
@ ngrx / entity - очень удобный способ нормализовать ваш магазин. посмотрите на этот @ ngrx / entity ReadMe.
Кроме того, он поставляется с мощным адаптером сущностей и селекторами.
Я уже использовал его в своем проекте. Но я считаю, что это не очень полезно с глубокой вложенной структурой магазина. И как я упоминаю для @Christian Benseler - у меня там нет идентификаторов, и имена могут быть одинаковыми
ОК. Однако выбор использования идентификатора полностью зависит от вас. Я рекомендую использовать uuid или другой тип генератора идентификаторов для вашего штата. по мере роста вашего приложения это будет полезно.
Большой! Спасибо. Но, как я уже упоминал,
nameможет быть таким же. Это будет работать, только если у меня будет уникальный идентификатор для каждого объекта, такого как id. Потому что это не сработает:children: { 'Address': [], 'Phone': '['Phone'], 'Phone': ['Phone'] }