首页 > 解决方案 > 异步更新的数组不会使用 *ngFor 更新 html。只有页面刷新有效。如何让它实时更新?

问题描述

在此处输入图像描述

应用组件

<app-navbar></app-navbar>
<div class="row">
  <div class="col-lg-4">
    <app-patients></app-patients>
  </div>
  <div class="col-lg-8">
    <router-outlet></router-outlet>
  </div>
</div>

服务

  private readonly URL = 'http://localhost:8080/api/patients';

  constructor(private httpClient: HttpClient) {
  }

  public getPatient(id: number): Observable<Patient> {
    const url = `${this.URL}/${id}`;
    return this.httpClient.get<Patient>(url);
  }

  public getPatients(): Observable<Patient[]> {
    console.log('inside service getPatients');
    return this.httpClient.get<Patient[]>(this.URL);
  }

  public addPatient(patient: Patient): Observable<Patient> {
    return this.httpClient.post<Patient>(this.URL, patient);
  }

PatientAddComponent 中的 addPatient 方法

constructor(private patientService: PatientService, private router: Router, private patientsComp: PatientsComponent) {
  }

  ngOnInit() {
  }

  addPatient() {
    this.patientService.addPatient(this.patient).subscribe((patient) => {
    //redirection to page with new patient. This part works fine.
    this.router.navigateByUrl(patient.id.toString());
      }
    ); 

带数组的组件

  patients: Patient[];

  constructor(private patientService: PatientService) {

  }

  ngOnInit() {
    console.log('inside patients on init');
    this.patientService.getPatients().subscribe(patients => {
      this.patients = patients;
    });
  }

console.log 显示该数组确实已更新,因此在这部分之前一切正常,但更改并未反映在患者组件的 html 代码中:

<div id="overflowControl">
  <div *ngFor="let patient of patients" class="list-group" id="list-tab" role="tablist" [routerLink]="['/', patient.id]">
    <div class="container">
      <a class="list-group-item list-group-item-action" id="list-home-list" data-toggle="list" href="#list-home"
         role="tab" aria-controls="home" (click)="toggleActive()">
        <div class="row">
          <div class="col-lg-9">
            <p class="pt-2 pl-2">{{patient.name}}</p>
            <p class="pl-2">{{patient.date | date: 'short'}}</p>
          </div>
          <div class="col-lg-3">
            <h3 class="pt-2"><i class="fa fa-female sex-icon" *ngIf="patient.sex == 'female'"></i></h3>
            <h3 class="pt-2"><i class="fa fa-male sex-icon" *ngIf="patient.sex == 'male'"></i></h3>
          </div>
        </div>
      </a>
    </div>
  </div>
</div>

我必须手动刷新浏览器页面,然后才能看到最近添加的对象列表。当添加新对象时,如何确保更新对象列表?这是我正在使用的 Angular 的当前版本:

角版

链接到 github 项目: https ://github.com/kolos181/med-records/tree/master/src/app/components

标签: angularasynchronousobservablengfor

解决方案


通过使用 EventEmitter 在组件之间创建共享服务解决了问题。更改代码:

中间服务.ts

import {EventEmitter, Injectable, Output} from '@angular/core';
import {Patient} from '../models/Patient';

@Injectable({
  providedIn: 'root'
})
export class IntermediateService {

  @Output() newPatient: EventEmitter<Patient> = new EventEmitter<Patient>();

  constructor() {
  }

  onNewPatient(patient: Patient) {
    this.newPatient.emit(patient);
  }
}

患者组件.ts

constructor(private patientService: PatientService, private interService: IntermediateService) {
  }
  ngOnInit() {
    this.interService.newPatient.subscribe(patient => {
      this.patients.unshift(patient);
    });
    //rest of code
}

患者-add.component.ts

  constructor(private patientService: PatientService, private router: Router, private interService: IntermediateService) {
  }
  addPatient() {
    this.patientService.addPatient(this.patient).subscribe((patient) => {
        this.interService.onNewPatient(patient);
    //rest of code
}

推荐阅读