如何使用 *ngIf 进行异步 http.get 数据请求 - Angular 2
How to use *ngIf for async http.get data request - Angular 2
我有一个 Web 应用程序正在从多个 api 中检索数据,并且应该将这些数据用于某些图表。问题是当图表被呈现时,来自 api 的数据还没有出现。我尝试使用 .then()
方法,但它告诉我 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>
如有任何问题或进一步的解释,请发表评论,我会立即回答。谢谢!
你忘了实现 OnInit [https://angular.io/guide/lifecycle-hooks][1]
export class AppComponent implements OnInit{
尝试为此组件使用 Resolver
[https://angular.io/api/router/Resolve][2]
只需使用一个布尔值来显示加载。
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
用于加载部分
<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>
我不明白你的问题到底是什么,请你再澄清一点。
但是如果你的问题是这些行
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
初始化后执行。
我有一个 Web 应用程序正在从多个 api 中检索数据,并且应该将这些数据用于某些图表。问题是当图表被呈现时,来自 api 的数据还没有出现。我尝试使用 .then()
方法,但它告诉我 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>
如有任何问题或进一步的解释,请发表评论,我会立即回答。谢谢!
你忘了实现 OnInit [https://angular.io/guide/lifecycle-hooks][1]
export class AppComponent implements OnInit{
尝试为此组件使用 Resolver [https://angular.io/api/router/Resolve][2]
只需使用一个布尔值来显示加载。
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
用于加载部分
<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>
我不明白你的问题到底是什么,请你再澄清一点。 但是如果你的问题是这些行
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
初始化后执行。