📜  当数据是数组时,ngxs 不推送更新状态 - Javascript (1)

📅  最后修改于: 2023-12-03 14:54:14.882000             🧑  作者: Mango

当数据是数组时,ngxs 不推送更新状态 - Javascript

在使用 NGXS 管理状态时,有时会遇到数据是数组的情况。不过,这种情况下可能会存在一个问题:当数组的值改变时,NGXS 不会推送更新状态。

问题描述

假设有一个数据存储了一个数组,我们想通过一个操作来修改数组中的某个元素。

@State({
  name: 'todos',
  defaults: {
    list: [1, 2, 3]
  }
})
export class TodosState {
  @Action(UpdateTodo)
  update(ctx: StateContext<TodosStateModel>, action: UpdateTodo) {
    const state = ctx.getState();
    const { list } = state;

    const index = list.findIndex(todo => todo.id === action.payload.id);
    const newList = [...list];
    newList[index] = action.payload;

    // Update state
    ctx.patchState({
      list: newList
    });
  }
}

上面的代码尝试使用 patchState 更新 list 数组,但是 NGXS 并不会自动推送更新状态。也就是说,当我们更新 list 数组时,组件不会更新它的视图。

解决方案

为了解决这个问题,我们需要在更新状态后手动触发变更检测。可以使用 Angular 提供的 ChangeDetectorRef 服务更新视图。

import { ChangeDetectorRef } from '@angular/core';

@State({
  name: 'todos',
  defaults: {
    list: [1, 2, 3]
  }
})
export class TodosState {
  constructor(private cdr: ChangeDetectorRef) {}

  @Action(UpdateTodo)
  update(ctx: StateContext<TodosStateModel>, action: UpdateTodo) {
    const state = ctx.getState();
    const { list } = state;

    const index = list.findIndex(todo => todo.id === action.payload.id);
    const newList = [...list];
    newList[index] = action.payload;

    // Update state
    ctx.patchState({
      list: newList
    });

    // Trigger change detection
    this.cdr.detectChanges();
  }
}

上面的代码调用 cdr.detectChanges(),手动触发变更检测,这将更新组件的视图。

结论

当使用 NGXS 管理状态时,你可能会遇到数据是数组的情况。如果在更新数组时,NGXS 不会自动推送更新状态,那么我们需要调用 ChangeDetectorRef.detectChanges() 手动触发变更检测。

希望这篇文章能够帮助你更好地了解如何处理数据是数组的情况。