Asynchronously updated array doesn't update ht

2019-03-04 14:23发布

enter image description here

appComponent

<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>

service

  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);
  }

addPatient method inside PatientAddComponent

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());
      }
    ); 

Component with array

  patients: Patient[];

  constructor(private patientService: PatientService) {

  }

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

console.log shows that array is indeed updated, so it looks like everything works fine up to this part, but changes are not reflected in html code of Patients component:

<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>

I have to manualy refresh browsers page and only then I would see objects list with recently added one. How do I make sure that list of objects is updated when new object is added to it? Here is the current version of Angular I am working with:

Angular version

link to github project: https://github.com/kolos181/med-records/tree/master/src/app/components

1条回答
地球回转人心会变
2楼-- · 2019-03-04 14:48

Problem was solved by creating a shared service between components with EventEmitter. Changed code:

intermediate.service.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);
  }
}

patientscomponent.ts

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

patient-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
}
查看更多
登录 后发表回答