Как правильно объединить срезы состояния для моего презентационного компонента (ngrx / store)?

Еще пытаюсь изучить ngrx - магазин настроен и вроде все нормально работает. Я использую базу данных SQL, поэтому в основном я «клонирую» таблицы и загружаю их в хранилище, но при выборе сотрудника в конце концов возникают проблемы с присоединением к состоянию.

Сущность сотрудника выглядит примерно так:

export class Employee = {
  id: number;
  firstName: string;
  lastName: string;
  degreeId?: number;
  degree: Degree;
}

export class Degree = {
  id: number;
  description: string;
}

Теперь в моем компоненте я хотел бы, чтобы конкретный сотрудник отображался следующим образом:

{
  id: 1,
  firstName: George,
  lastName: Costanza,
  degreeId: 2,
  degree: {
    id: 2,
    description: 'College'
  }
}

Я попытался создать селектор, объединяющий эти две сущности:

export const getEmployeeWithAllData = createSelector(
  getSelectedEmployee,
  getRelationalData,
  (employee, data) => {
    const employeesDegree = degree[employee.degreeId]
    employee.degree = employeesDegree

    return employee;
  }
);

Кажется, это работает, если я не использую ngrx-store-freeze - поэтому, поскольку я не знаю, правильно ли я создаю селектор или есть ли в ngrx-store-freeze ошибка, я задаю этот вопрос.

Действительно ли я изменяю состояние, когда это делаю?

Если да, как я могу выбрать конкретного сотрудника из своего магазина со всеми имеющимися у него реляционными данными?

То, что я делаю, мне кажется неправильным. В моем реальном приложении у сотрудника около 8 полей реляционных данных, к которым мне нужно присоединиться ...

Изменить: я забыл включить ошибку ngrx-store-freeze throws:

ERROR TypeError: Cannot assign to read only property 'degree' of object '[object Object]'
at eval (employee.selector.ts:85)
at eval (store.es5.js:602)
at memoized (store.es5.js:539)
at defaultStateFn (store.es5.js:573)
at eval (store.es5.js:605)
at MapSubscriber.memoized [as project] (store.es5.js:539)
at MapSubscriber._next (map.js:79)
at MapSubscriber.Subscriber.next (Subscriber.js:95)
at MapSubscriber._next (map.js:85)
at MapSubscriber.Subscriber.next (Subscriber.js:95)

person rawk    schedule 20.04.2018    source источник
comment
Да, вы меняете состояние при попытке назначить employee.degree. Есть несколько способов решить эту проблему. Сначала сделайте обратное, установите степень для сотрудника до, когда он попадет в магазин. Во-вторых, используется объект-оболочка из вашего селектора, например {сотрудник, степень}.   -  person bc1105    schedule 20.04.2018
comment
Спасибо! Получил работу с объектом-оболочкой :)   -  person rawk    schedule 20.04.2018


Ответы (1)


да, вы пытаетесь видоизменить состояние. Вы можете предотвратить это просто, как показано ниже.

export const getEmployeeWithAllData = createSelector(
  getSelectedEmployee,
  getRelationalData,
  (employee, data) => {
    const emp = JSON.parse(JSON.stringify(employee)
    emp.degree = degree[employee.degreeId]

    return emp;
  }
)
person Ajantha Bandara    schedule 21.04.2018
comment
Была такая же идея, чтобы решить эту проблему, но это вызвало некоторую (на мой взгляд) ошибку. Возвращая глубокую копию из селектора, он заставлял NgRx запускать события публикации на подписчиках этого селектора, когда запускался эффект с тем же объектом (даже если эффект не изменил состояние). Вы использовали это решение в аналогичной сложной настройке и можете подтвердить, что у вас не было такого поведения с ошибками? - person Recek; 08.08.2019