嵌套孩子的ngxs状态更改

时间:2019-09-20 13:22:47

标签: angular ngxs

我正在尝试更新处于我的状态的嵌套子级,但是总是以错误“不能分配为只读属性”结尾。这可能是由于我正在使用不可变状态。但是我该如何改变那个嵌套孩子呢?

代码如下:

@Action(UpdatePortalLogo)
updatePortalLogo(
    ctx: StateContext<PortalStateModel>,
    { logo }: UpdatePortalLogo
) {
    const state = ctx.getState();
    let portal = state.portals.find((portal) => portal.id === state.portalId);
    portal.style.logo = logo; //-> this is the line where it fails

    ctx.setState(
        patch({
            portals: updateItem<Portal>(p => p.id === ctx.getState().portalId,
                portal)
        }));
}

我的状态模型如下:

 export interface PortalStateModel {
       portals: Portal[];
       portalId: string;
       loaded: boolean;
       loading: boolean;
    }

我是否需要使用子状态才能工作?

1 个答案:

答案 0 :(得分:1)

这是因为NGXS在开发模式下使用deepFreeze。您可以通过以下方式进行检查:

console.log(Object.isFrozen(portal));

您可以通过在导入根模块时将developmentMode设置为false来将其关闭:

NgxsModule.forRoot([], { developmentMode: false })

但是您不想这样做,因为“冻结”会阻止您进行不可预测的突变。

破坏是您的武器:

const portal = { ...state.portals.find((portal) => portal.id === state.portalId) };

此外,updateItem运算符可以将函数用作第二个参数,您可以在其中更新对象。结果,代码变得更具说明性:

ctx.setState(
  patch({
    portals: updateItem(
      portal => portal.id === state.portalId,
      portal => {
        const newPortal = { ...portal };
        newPortal.style.logo = logo;
        return newPortal;
      }
    )
  })
);