Изменение состояния ngxs для вложенного потомка - PullRequest
1 голос
/ 20 сентября 2019

Я пытаюсь обновить вложенный дочерний элемент в моем состоянии, но всегда получаю сообщение об ошибке «невозможно назначить свойство только для чтения».Вероятно, это связано с тем, что я работаю с неизменным состоянием.Но как я могу изменить этого вложенного потомка?

Вот код:

@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 Ответ

1 голос
/ 22 сентября 2019

Это потому, что 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;
      }
    )
  })
);
...