2017-03-26 11 views
2

我對angular2完全陌生。我的問題是我通過ng2-charts lib創建了條形圖,並使用angularfire2將它鏈接到了firebase。 我有2個組件和一個向我的Firebase數據庫發送和接收數據的服務。我可以通過我的data.service.ts將一個組件doctor-local.component.ts中的數據發送到firebase中,並通過我的doctor-expert.component.ts接收數據,並使用(ngModelChange)事件綁定將這些數據保持同步,以根據Firebase數據庫中的值進行更改並實時顯示。條形圖也在這個組件中。如何通過firebase實時異步更新ng2圖表中的值

這是我expert.component.tsdoctor-expert.component.html

import {Component} from '@angular/core'; 
 
import {DataService} from '../data.service'; 
 
import {FirebaseObjectObservable} from 'angularfire2'; 
 

 
@Component({ 
 
    selector: 'app-doctor-expert', 
 
    templateUrl: './doctor-expert.component.html', 
 
    styleUrls: ['./doctor-expert.component.css'] 
 
}) 
 
export class DoctorExpertComponent { 
 
    public items: FirebaseObjectObservable<any>; 
 
    
 
    public barChartOptions: any = { 
 
    scaleShowVerticalLines: false, 
 
    responsive: true 
 
    }; 
 
    public barChartLabels: string[] = ['RBC Count', 'WBC Count', 'Haemoglobin']; 
 
    public barChartType: string = 'bar'; 
 
    public barChartLegend: boolean = true; 
 
    rbc: number; 
 
    wbc: number; 
 
    haemo: number; 
 

 

 
    public barChartData: any[] = [ 
 
    {data: [75, 59, 80], label: 'Current Count'}, 
 
    {data: [28, 48, 40], label: 'Average Normal Count'} 
 
    ]; 
 

 
    constructor(private dataService: DataService) { 
 
    this.items = this.dataService.messages; 
 
    this.items.subscribe(data => { 
 
     this.rbc = parseInt((data.rbccount), 10); 
 
     this.wbc = parseInt((data.wbccount), 10); 
 
     this.haemo = parseInt((data.haemocount), 10); 
 
    }); 
 
    this.barChartData = [ 
 
     {data: [this.rbc, this.wbc, this.haemo], label: 'Current Count'}, 
 
     {data: [50, 50, 50], label: 'Average Normal Count'}, 
 
    ]; 
 
    } 
 

 
    
 
    public chartClicked(e: any): void { 
 
    console.log(e); 
 
    } 
 

 
    public chartHovered(e: any): void { 
 
    console.log(e); 
 
    } 
 
}
<ul class="list-group container"> 
 
    <li class="list-group-item">RBC Count: {{(items | async)?.rbccount}} </li> 
 
    <li class="list-group-item">WBC Count: {{(items | async)?.wbccount}} </li> 
 
    <li class="list-group-item">Haemoglobin Count: {{(items | async)?.haemocount}} </li> 
 
</ul> 
 

 
<div class="container"> 
 
    <div style="display: block"> 
 
    <canvas baseChart 
 
      [datasets]="barChartData" 
 
      [labels]="barChartLabels" 
 
      [options]="barChartOptions" 
 
      [legend]="barChartLegend" 
 
      [chartType]="barChartType" 
 
      (chartHover)="chartHovered($event)" 
 
      (chartClick)="chartClicked($event)"></canvas> 
 
    </div> 
 
</div>

這裏是我的data.service.ts

import {Injectable} from '@angular/core'; 
 
import 'rxjs/Rx'; 
 
import {AngularFire, FirebaseObjectObservable} from 'angularfire2'; 
 

 
@Injectable() 
 
export class DataService { 
 
    public messages: FirebaseObjectObservable<any>; 
 

 
    constructor(public af: AngularFire) { 
 
    this.messages = this.af.database.object('data'); 
 
    } 
 

 

 
    sendData(value1, value2, value3) { 
 
    const message = { 
 
     rbccount: value1, 
 
     wbccount: value2, 
 
     haemocount: value3 
 
    }; 
 
    this.messages.update(message); 
 
    } 
 

 
    sendrbc(value){ 
 
    const message = { 
 
     rbccount: value 
 
    }; 
 
    this.messages.update(message); 
 
    } 
 

 
    sendwbc(value2){ 
 
    const message = { 
 
     wbccount: value2 
 
    }; 
 
    this.messages.update(message); 
 
    } 
 

 
    sendhaemo(value3){ 
 
    const message = { 
 
     haemocount: value3 
 
    }; 
 
    this.messages.update(message); 
 
    } 
 
}

「this.items = this.dataService.messages」從數據庫接收代碼,subscribe方法從observable獲取值。現在我想更新barChartData中收到的這個值,並保持它與數據庫中的更改保持同步。因此,每當通過doctor-local.component.ts的數據發生變化時,數據庫和條形圖都會立即發生變化。我試圖在構造函數中這樣做,但數據並沒有顯示在條形圖中,更不用說不斷更​​新。

回答

3

我做了一些挖掘,並提出了這個非常簡單的解決方案。 問題在於數據集異步加載,並且圖表在init時正在呈現,這就是爲什麼它無法加載到達的新數據。

解決方法是等待繪製畫布,直到完成異步。在您的組件:

isDataAvailable:boolean = false; ngOnInit() { asyncFnWithCallback(()=>{ this.isDataAvailable = true}); }

其中asyncFnWithCallback()是你的函數。

然後在你的HTML,包住整個圖表模板,:

<div *ngIf="isDataAvailable"> . . . chart canvas + any other template code . . . </div>

在這種情況下,爲doctor-expert.component.ts,新的代碼看起來是這樣的:

import {Component, OnInit} from '@angular/core'; 
 
import {DataService} from '../data.service'; 
 
import {FirebaseObjectObservable} from 'angularfire2'; 
 

 
@Component({ 
 
    selector: 'app-doctor-expert', 
 
    templateUrl: './doctor-expert.component.html', 
 
    styleUrls: ['./doctor-expert.component.css'] 
 
}) 
 
export class DoctorExpertComponent{ 
 
    public items: FirebaseObjectObservable<any>; 
 

 
    public barChartOptions: any = { 
 
    scaleShowVerticalLines: false, 
 
    responsive: true 
 
    }; 
 
    public barChartLabels: string[] = ['RBC Count', 'WBC Count', 'Haemoglobin']; 
 
    public barChartType: string = 'bar'; 
 
    public barChartLegend: boolean = true; 
 
    rbc: number; 
 
    wbc: number; 
 
    haemo: number; 
 

 

 
    public barChartData: any[] = []; 
 

 
    isDataAvailable: boolean = false; 
 

 
    constructor(private dataService: DataService) { 
 
    this.items = this.dataService.messages; 
 
    this.items.subscribe(data => { 
 
     this.rbc = parseInt((data.rbccount), 10); 
 
     this.wbc = parseInt((data.wbccount), 10); 
 
     this.haemo = parseInt((data.haemocount), 10); 
 
     this.barChartData = [ 
 
     {data: [this.rbc, this.wbc, this.haemo], label: 'Current Count'}, 
 
     {data: [50, 50, 50], label: 'Average Normal Count'}, 
 
     ]; 
 
     this.isDataAvailable = true; 
 
    }); 
 
    } 
 

 

 
    public chartClicked(e: any): void { 
 
    console.log(e); 
 
    } 
 

 
    public chartHovered(e: any): void { 
 
    console.log(e); 
 
    } 
 
}

doctor-expert.component.html看起來像這樣:

<ul class="list-group container"> 
 
    <li class="list-group-item" (ngModelChanges)="update($event)">RBC Count: {{(items | async)?.rbccount}} </li> 
 
    <li class="list-group-item" (ngModelChanges)="update($event)">WBC Count: {{(items | async)?.wbccount}} </li> 
 
    <li class="list-group-item" (ngModelChanges)="update($event)">Haemoglobin Count: {{(items | async)?.haemocount}} </li> 
 
</ul> 
 

 
<div class="container" *ngIf="isDataAvailable"> 
 
    <div style="display: block"> 
 
    <canvas baseChart 
 
      [datasets]="barChartData" 
 
      [labels]="barChartLabels" 
 
      [options]="barChartOptions" 
 
      [legend]="barChartLegend" 
 
      [chartType]="barChartType" 
 
      (chartHover)="chartHovered($event)" 
 
      (chartClick)="chartClicked($event)"></canvas> 
 
    </div> 
 
</div>