Angular:NGXS:WebSocket 更新了状态但未更新 UI

Angular : NGXS : WebSocket updated the state but not UI

我在 Angular 项目中使用 NGXS 实现状态管理,状态由 NGXS 的插件 WebSocket 更新

我实现了什么:

model.ts

export interface Student {
  id: string;
  name: string;
  passed: boolean;
}

student.action.ts

export class GetStudents{
 ...
}
export class UpdateStatus {
  static readonly type = '[Student] Update Status';
  constructor( studentId: string ) {}
}

student.state.ts

...
export class StudentStateModel {
  students: Student[];
}

@State<StudentStateModel>({
  name: 'student',
  defaults: {
    students: []
  }
})

@Action(GetStudents)
... 

@Action(UpdateStatus)
  updateStatus(
    { getState, setState }: StateContext<StudentStateModel>,
    { studentId }: UpdateStatus
  ) {
  
    const students = getState().students;
    const index = students.findIndex((i) => i.id === studentId);

    setState((state: ApprovalStateModel) => {
      state.students[index].passed = true;
      return state;
    });
  }
...

我实现了 2 个组件(父组件和子组件):

1/父组件保留学生列表

students$: Observable<any>; // Get list of Students from Store GetStudents

students.component.html

<div *ngFor= "let student of students$ | async">
    <app-student-detail
      [student] = "student"
    ></app-student-detail>
  </div>

2/子组件保留学生详细信息,它包括一个输入

@Input() student: Student = null;

学生-detail.component.html

<div *ngIf="student">
    <p>Id: {{student.id}}</p>
    <p>Name: {{student.name}}</p>
    <p>Result: {{student.passed}} </p>
  </div

我用WebSocket插件更新学生状态,我发消息了

 {"type": "[Student] Update Status", "studentId" : "10001"}

结果:

从日志中,学生 ID 10001 的状态已成功更新为 passed = true,但从 UI 开始,结果未更新。

我的实现有问题,欢迎任何建议。

尝试使用状态运算符来更新状态。例如,您可以使用 updateItem 查找和更新数组中的项目:

import { patch, updateItem } from '@ngxs/store/operators';
    
...

@Action(UpdateStatus)
updateStatus(ctx: StateContext<StudentStateModel>, { studentId }: UpdateStatus) {
  ctx.setState(
    patch({
      students: updateItem<Student>(
        student => student.studentId === studentId,
        student => ({
          ...student,
          passed: true
        })
      )
    })
  );
}