[英]How to use *ngIf for async http.get data request - Angular 2
我有一個Web應用程序,該應用程序正在從多個api檢索數據,並且應該將數據使用到一些圖表中。 問題在於,當圖表被渲染時,來自api的數據還沒有。 我嘗試使用.then()
方法,但它告訴我, property then does not exist on type void
該property then does not exist on type void
。 此外,在此答案之后 ,我嘗試使用ngIf
方法,但也不起作用。 你知道我該怎么解決嗎?
以下是我的組件和組件模板。
app.component.ts
import { Component } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/Rx';
import * as moment from 'moment';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'Mimesi dashboard graphs';
//COUNTS
public countIndexerMetaApi; //array of one number populated from http.get
public countIndexerMetaNumber; //number extracted into array and stored as an int
public countIndexerMetaArray; //array to store countNumber afterwards
public countIndexerServedApi;
public countIndexerServedNumber;
public countIndexerServedArray;
public countRealTimeServedApi;
public countRealTimeServedNumber;
public countRealTimeServedArray;
//DATES
public dateIndexerMetaToStore; //date got from moment method that needs to be stored
public dateIndexerMetaArray; //array to store dates for graph label
public dateIndexerServedToStore;
public dateIndexerServedArray;
public dateRealTimeServedToStore;
public dateRealTimeServedArray;
//API LINKS
private apiCountIndexerMetaUrl: string = 'http://localhost:3000/api/countIndexerMetaApi';
/* TODO - API FOR COUNT OF OTHER TWO TABLES */
private apiCountIndexerServedUrl: string = 'http://localhost:3000/api/countIndexerServedApi';
private apiCountRealTimeServedUrl: string = 'http://localhost:3000/api/countRealTimeServedApi';
//VARIABLE FOR TIMEOUT
public isDataAvailable:boolean = false;
constructor(private http:Http) {
let now = moment.locale("it");
//COUNT
this.countIndexerMetaApi = 0;
this.countIndexerMetaNumber = 0;
this.countIndexerMetaArray = [];
this.countIndexerServedApi = 0;
this.countIndexerServedNumber = 0;
this.countIndexerServedArray = []
this.countRealTimeServedApi = 0;
this.countRealTimeServedNumber = 0;
this.countRealTimeServedArray = []
//DATES
this.dateIndexerMetaToStore = "";
this.dateIndexerMetaArray = [];
this.dateIndexerServedToStore = "";
this.dateIndexerServedArray = [];
this.dateRealTimeServedToStore = "";
this.dateRealTimeServedArray = [];
}
ngOnInit() {
this.getIndexerMetaCount();
this.getIndexerServedCount();
this.getRealTimeServedCount();
}
//COUNT
getIndexerMetaCount(){
this.http.get(this.apiCountIndexerMetaUrl)
.map((res: Response) => res.json())
.subscribe(
data => {
console.log(this.countIndexerMetaApi = data.map(countIndexerMetaApiObj => countIndexerMetaApiObj.countIndexerMetaApi))
},
);
//this.countIndexerMetaNumber = this.countIndexerMetaApi[0]; //<-- timing problem since this.count is not yet got from http.get() so it seems undefined
//this.countIndexerMetaArray.push(this.countIndexerMetaNumber); // problem follows through
}
printCountIndexerMetaArray(){
this.countIndexerMetaApi.forEach(element => {
console.log(element);
});
}
getIndexerServedCount(){
this.http.get(this.apiCountIndexerServedUrl)
.map((res: Response) => res.json())
.subscribe(
data => {
console.log(this.countIndexerServedApi = data.map(countObj => countObj.countIndexerServedApi))
},
);
//this.countIndexerServedNumber = this.countIndexerServedApi[0]; //<-- timing problem since this.count is not yet got from http.get() so it seems undefined
//this.countIndexerServedArray.push(this.countIndexerServedNumber); // problem follows through
}
printCountIndexerServedArray(){
this.countIndexerServedApi.forEach(element => {
console.log(element);
});
}
getRealTimeServedCount(){
this.http.get(this.apiCountRealTimeServedUrl)
.map((res: Response) => res.json())
.subscribe(
data => {
console.log(this.countRealTimeServedApi = data.map(countObj => countObj.countRealTimeServedApi))
},
);
//this.countRealTimeServedNumber = this.countRealTimeServedApi[0]; //<-- timing problem since this.count is not yet got from http.get() so it seems undefined
//this.countRealTimeServedArray.push(this.countRealTimeServedNumber); // problem follows through
}
printRealTimeServedArray(){
this.countRealTimeServedApi.forEach(element => {
console.log(element);
});
}
//DATES
dateIndexerMeta() {
this.dateIndexerMetaToStore = moment().add(-122, 'days');
this.dateIndexerMetaArray.push(this.dateIndexerMetaToStore);
}
dateIndexerServed() {
this.dateIndexerServedToStore = moment().add(-122, 'days');
this.dateIndexerServedArray.push(this.dateIndexerServedToStore);
}
dateRealTimeServed() {
this.dateRealTimeServedToStore = moment().add(-122, 'days');
this.dateRealTimeServedArray.push(this.dateRealTimeServedToStore);
}
//TIMEOUT TRIAL
timeoutTrial(){
console.log(this.isDataAvailable);
setTimeout(function() {this.isDataAvailable = true;
console.log(this.isDataAvailable);
}, 5000); //<-- timeout works but other functions don't refresh even if isDataAvailable changed
}
/* CHARTS */
//DATA
public lineChartData:Array<any> = [
{data: this.countIndexerMetaArray, label: 'Indexer meta served links'},
];
public lineChartData1:Array<any> = [
{data: this.countIndexerServedArray, label: 'Indexer served links'},
];
public lineChartData2:Array<any> = [
{data: this.countRealTimeServedArray, label: 'Real-Time served links'},
];
//LABELS
public lineChartLabels:Array<any> = this.dateIndexerMetaArray;
public lineChartLabels1:Array<any> = this.dateIndexerServedArray;
public lineChartLabels2:Array<any> = this.dateRealTimeServedArray;
//OPTIONS
public lineChartOptions:any = {
responsive: true,
scales: {
xAxes: [{
type: 'time',
time: {
displayFormats: {
'millisecond': 'DD MMM',
'second': 'DD MMM',
'minute': 'DD MMM',
'hour': 'DD MMM',
'day': 'DD MMM',
'week': 'DD MMM',
'month': 'DD MMM',
'quarter': 'DD MMM',
'year': 'DD MMM',
}
}
}],
},
};
public lineChartLegend:boolean = true;
public lineChartType:string = 'line';
//COLORS
public lineChartColors:Array<any> = [
{ // grey
backgroundColor: 'rgba(255,55,55,0.2)',
borderColor: 'rgba(255,55,55,1)',
pointBackgroundColor: 'rgba(255,55,55,1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(255,55,55,0.8)'
},
];
//EVENTS
public chartClicked(e:any):void {
console.log(e);
}
public chartHovered(e:any):void {
console.log(e);
}
}
app.component.html
<div class="container">
<div class="front-end-app">
<ul>
<h3>Count Indexer Meta:</h3>
<li *ngFor="let countIndexerMetaNumber of countIndexerMetaApi">
{{countIndexerMetaNumber}}
</li>
<h3>Count Indexer Served:</h3>
<li *ngFor="let countIndexerServedNumber of countIndexerServedApi">
{{countIndexerServedNumber}}
</li>
<h3>Count Real Time Served:</h3>
<li *ngFor="let countRealTimeServedNumber of countRealTimeServedApi">
{{countRealTimeServedNumber}}
</li>
</ul>
<hr>
<div class="head">
<h1>{{title}}</h1>
</div>
<hr>
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-block">
<canvas baseChart width="600" height="400"
[datasets]="lineChartData"
[labels]="lineChartLabels"
[options]="lineChartOptions"
[colors]="lineChartColors"
[legend]="lineChartLegend"
[chartType]="lineChartType"
(chartHover)="chartHovered($event)"
(chartClick)="chartClicked($event)"></canvas>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-block">
<canvas baseChart width="600" height="400"
[datasets]="lineChartData1"
[labels]="lineChartLabels1"
[options]="lineChartOptions"
[colors]="lineChartColors"
[legend]="lineChartLegend"
[chartType]="lineChartType"
(chartHover)="chartHovered($event)"
(chartClick)="chartClicked($event)"></canvas>
</div>
</div>
</div>
<div class="col-md-6 offset-md-3">
<div class="card">
<div class="card-block">
<canvas baseChart width="600" height="400"
[datasets]="lineChartData2"
[labels]="lineChartLabels2"
[options]="lineChartOptions"
[colors]="lineChartColors"
[legend]="lineChartLegend"
[chartType]="lineChartType"
(chartHover)="chartHovered($event)"
(chartClick)="chartClicked($event)"></canvas>
</div>
</div>
</div>
</div>
</div>
<button type="button" class="btn btn-primary" (click)="printCountIndexerMetaArray()"> Click to print count indexer meta array</button>
<button type="button" class="btn btn-primary" (click)="printCountIndexerServedArray()"> Click to print count indexer served array</button>
<button type="button" class="btn btn-primary" (click)="printRealTimeServedArray()"> Click to print count real time served array</button>
</div>
對於任何問題或進一步的解釋,請發表評論,我會立即回答。 謝謝!
只需使用布爾值顯示加載即可。
public isloading = true;
在您的http調用中,一旦獲得所需的所有數據,請將其設置為false。
this.http.get(this.apiCountRealTimeServedUrl)
.map((res: Response) => res.json())
.subscribe(
data => {
this.countRealTimeServedApi =
data.map(countObj => countObj.countRealTimeServedApi);
this.isloading= false;
},
);
在您的HTTP中有ngIf
作為isloading部分
<div *ngIf="isloading" > loading .... </div>
<div *ngIf="!isloading" >
<!-- show the chart contents -->
</div>
如果您有多個HTTP調用,請使用&&
<div *ngIf="isIndexMetaCountloading
|| isIndexerServedCountLoading
|| isRealTimeServedCountLoading" >
loading ...
</div>
<div *ngIf="!isIndexMetaCountloading
&& !isIndexerServedCountLoading
&& isRealTimeServedCountLoading" >
<!-- show the chart contents -->
</div>
你忘了實現OnInit [ https://angular.io/guide/lifecycle-hooks][1]
export class AppComponent implements OnInit{
嘗試對此組件使用Resolver [ https://angular.io/api/router/Resolve][2]
我沒有弄清楚您的問題是什么,請您再澄清一下。 但是如果您的問題在於這些行
this.countIndexerServedNumber = this.countIndexerServedApi[0];
//<-- timing problem since this.count is not yet
// got from http.get() so it seems undefined
this.countIndexerServedArray.push(this.countIndexerServedNumber);
// problem follows through
則它不起作用,因為get方法異步工作,因此this.countIndexerServedApi
尚未初始化。 因此,要解決此問題,您應該將這些語句移到this.countIndexerServedApi
塊內,然后僅在this.countIndexerServedApi
初始化后才執行這些語句。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.