无法使用 Observable 更新 Angular 2 中的列表

Can't update list in Angular 2 using Observable

我正在使用 angular 2 和 socket.io 一起加载数据并使用 socket.io

重新加载更改

我有一个从 API:

加载数据的服务
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
import * as io from 'socket.io-client';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { Call } from '../model/call';
import * as globals from '../../globals';

@Injectable()
export class CallService {

  private socket;

  constructor(private http: Http) { }

    /**
     * Load all calls data from server.
     * @method loadCalls
     *
     * @return {Observable<Call[]>}
     */
  loadCalls(): Observable<Call[]> {
    return this.http
      .get(globals.server + globals.apiRoutes['calls'])
      .map(res => {
        return res.json();
      });
  }

  /**
   * Observer for call's mission time changing
   * @method callObserver
   * @return {Observable<any>}
   */
  callObserver() :Observable<any>{
    let observable = new Observable(observer => {
      this.socket = io.connect(globals.socketioServer);
      this.socket.on('call-channel:App\Events\CallEvent' , data => {
        observer.next(data);
      });
      return () => {
        this.socket.disconnect();
      }
    });
    return observable;
  }

}

loadCalls 方法在应用程序启动时加载所有调用数据,callObserver 方法侦听来自服务器的任何广播更改。 call-component.ts文件是:

import { Component, OnInit, OnDestroy ,Input} from '@angular/core';
import * as io from 'socket.io-client';
import { CallService } from './service/call.service';
import { Call } from './model/call';
import { Observable } from 'rxjs/Observable';

@Component({
  selector: 'app-call-status',
  templateUrl: './call-status.component.html',
  styleUrls: ['./call-status.component.css'],
  providers: [
    CallService,
  ],
})
export class CallStatusComponent implements OnInit, OnDestroy  {

  private connection;

  private calls: Call[] = new Array();

  private noMissionCalls: Call[] = new Array();

  private backToBaseCalls: Call[] = new Array();

  private finishMissionCalls: Call[] = new Array();

  private deliveredpatientCalls: Call[] = new Array();

  private arriveHospitalCalls: Call[] = new Array();

  private moveFromCalls: Call[] = new Array();

  private arrivedCalls: Call[] = new Array();

  private startMissionCalls: Call[] = new Array();

  private notifyMissionCalls: Call[] = new Array();

  constructor(private callService: CallService) {

  }

  ngOnInit() {

    this.classifyCalls(); //load calls data

    //listen for changes from server
    this.connection = this.callService.callObserver().subscribe(function(res) {
      let call: Call = res.data ? res.data[0] : null;
      if (call) {
        console.log(call);
      }

    });


  }

  ngOnDestroy() {
    this.connection.unsubscribe();
  }


  classifyCalls() {

    this.calls = new Array();
    this.noMissionCalls = new Array();
    this.backToBaseCalls = new Array();
    this.finishMissionCalls = new Array();
    this.deliveredpatientCalls = new Array();
    this.arriveHospitalCalls = new Array();
    this.moveFromCalls = new Array();
    this.arrivedCalls = new Array();
    this.startMissionCalls = new Array();
    this.notifyMissionCalls = new Array();

    this.callService.loadCalls().subscribe(calls =>{
      for(let item of calls){
        this.classifySingleCall(item);
      }
    });
  }

  classifySingleCall(call: Call) {
    if (call.mission_times == null) {
      call.status_name = 'noMissionCalls'
      this.noMissionCalls.push(call);

    } else if (call.mission_times.back_base) {
      call.status_name = 'backToBaseCalls';
      this.backToBaseCalls.push(call);

    } else if (call.mission_times.finish_mission) {
      call.status_name = 'finishMissionCalls';
      this.finishMissionCalls.push(call);

    } else if (call.mission_times.deliver_patient) {
      call.status_name = 'deliveredpatientCalls';
      this.deliveredpatientCalls.push(call);

    } else if (call.mission_times.arrive_hospital) {
      call.status_name = 'arriveHospitalCalls';
      this.arriveHospitalCalls.push(call);

    } else if (call.mission_times.move_from) {
      call.status_name = 'moveFromCalls';
      this.moveFromCalls.push(call);

    } else if (call.mission_times.arrived_urgency) {
      call.status_name = 'arrivedCalls';
      this.arrivedCalls.push(call);

    } else if (call.mission_times.start_mission) {
      call.status_name = 'startMissionCalls';
      this.startMissionCalls.push(call);

    } else if (call.mission_times.notify_mission || call.mission_times.get_message) {
      call.status_name = 'notifyMissionCalls';
      this.notifyMissionCalls.push(call);

    } else {
      call.status_name = 'noMissionCalls';
      this.noMissionCalls.push(call);
    }

    return call;
  }


}

加载数据在应用程序启动时完成。 但问题在这里:当呼叫更改广播到所有客户端时,我可以使用放置在 ngOnInit()

中的代码接收此呼叫的数据
 this.connection = this.callService.callObserver().subscribe(function(res) {
      let call: Call = res.data ? res.data[0] : null;
      if (call) {
        console.log(call);//log the call

        console.log(this.calls);//undefined
      }

    });

但是我无法在代码的 if 语句中访问 this.calls 数据。 调用数据加载在 ngOnInit 的第一行。 如何访问 this.classifyCalls(); 方法填充的数据?

在使用打字稿时,不要在 classes 中使用单词 function。这会将 class 的 this 上下文替换为您刚刚定义的函数的上下文。使用箭头符号:

this.connection = this.callService.callObserver().subscribe((res) => { //<-- here
   let call: Call = res.data ? res.data[0] : null;
   if (call) {
      console.log(call);//log the call
       console.log(this.calls);//undefined
   }

});