【问题标题】:How do I merge slices of state for my presentational component properly (ngrx/store)?如何正确合并我的演示组件的状态片段(ngrx/store)?
【发布时间】:2018-04-20 13:54:06
【问题描述】:

我仍在尝试学习 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)

【问题讨论】:

  • 是的,您在尝试分配给employee.degree 时正在改变状态。有几种方法可以解决这个问题。首先做相反的事情,设置员工进入商店之前的度数。其次是使用选择器中的包装器对象,例如 {employee, degree }。
  • 谢谢!让它与包装器对象一起工作:)

标签: ngrx ngrx-store ngrx-entity


【解决方案1】:

是的,您正在尝试改变状态。您可以像下面这样简单地防止这种情况

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

    return emp;
  }
)

【讨论】:

  • 有同样的想法来解决它,但它导致了一些(在我看来)错误的行为。通过从选择器返回一个深层副本,当触发具有相同对象的效果时(即使效果没有改变状态),它会导致 NgRx 触发该选择器的订阅者上的发布事件。您是否在类似的复杂设置中使用此解决方案并且可以确认您没有这种错误行为?
猜你喜欢
  • 2017-03-02
  • 2019-06-07
  • 2018-08-27
  • 2017-01-12
  • 2020-11-06
  • 2020-03-21
  • 2019-07-24
  • 2016-12-28
  • 1970-01-01
相关资源
最近更新 更多