【发布时间】:2018-07-12 22:16:36
【问题描述】:
全部:
我是 Angular 6 的新手,一直在学习如何使用表格显示数据。我对静态数据没有任何问题——也就是说,数组中的数据是静态定义的,就像在网上到处可见的众多示例中一样。我感到困惑的地方是处理从版本 4 以来 Angular 提供的(新)HttpClient 返回的数据。
我定义了一个具有 5 个属性的对象,所有这些属性都存储在不同服务器上的 MySQL 表中。该服务器上的 PHP 脚本返回一个包含 25 个 JSON 对象的数组,其中定义了这些属性。
我调用这个服务的方法是:
table-demo-components.ts
import { Component, OnInit } from '@angular/core';
import { FltdataHttpService } from '../fltdatahttp.service';
// Sorting support
import { ViewChild } from '@angular/core'; // new decorator
import { MatSort, MatTableDataSource, MatPaginator } from '@angular/material';
// Data are supplied by a service
var FLIGHTS = new Array();
@Component({
selector: 'app-table-demo',
templateUrl: './table-demo.component.html',
styleUrls: ['./table-demo.component.css']
})
export class TableDemoComponent implements OnInit {
// specify which columns are to show
displayedColumns: string[] = [
'flightNum',
'destinationCity',
'schedTime',
'actualTime',
'remarks'
]; // NOTE: these are the columns/properties as strings!
// this is how you handle sorted data
flightDataSource = new MatTableDataSource(this.flightDataService.FLIGHTS);
//flightDataSource = new MatTableDataSource(FLIGHTS); // note the difference
dummyNum: number;
// Add decorators for sort and pagination
@ViewChild(MatSort) sort: MatSort;
@ViewChild(MatPaginator) paginator: MatPaginator;
ngOnInit() {
this.flightDataSource.sort = this.sort;
}
// Inject HTTP support - flightDataService - not flightDataSource
constructor(public flightDataService: FltdataHttpService) {
console.log(">>> constructor fired; flightDataService = " + flightDataService);
}
// Support for pagination - note it comes in this and not ngOnInit()
ngAfterViewInit() {
//************************************
// IT MUST BE IN THIS ORDER!
//************************************
// flightDataSource is set here
FLIGHTS = this.flightDataService.getFlightData(); // get the actual data first
console.log(">>> FLIGHTS local = " + FLIGHTS.length);
this.flightDataSource = new MatTableDataSource(FLIGHTS); // then pass it to the source
this.flightDataSource.paginator = this.paginator; // then attached the paginator
this.flightDataSource.sort = this.sort; // and last, the sort option
}
}
在其他地方,我定义了一个服务来调用 http.get 方法:
fltdatahttp.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { FlightInfo } from './table-demo/flight-info';
var newFlight;
@Injectable({
providedIn: 'root'
})
export class FltdataHttpService {
public httpData: any;
public FLIGHTS: FlightInfo[] = [];
constructor(public http: HttpClient) {
//this.getFlightData();
}
public getFlightDataLocally(): FlightInfo[] {
console.log(">>> getFlightDataLocally() fired");
this.FLIGHTS = [
{flightNum: '145', destinationCity: 'Chicago Midway', schedTime: '17:35', actualTime: 'ON TIME', remarks: 'AMBASSADOR SERVICE'},
{flightNum: '365', destinationCity: 'Toronto Pearson', schedTime: '17:46', actualTime: 'ON TIME', remarks: 'NON-STOP'},
{flightNum: '277', destinationCity: 'Montreal Trudeau', schedTime: '17:51', actualTime: 'ON TIME', remarks: 'NON-STOP'},
{flightNum: '980', destinationCity: 'New York LaGuardia', schedTime: '17:58', actualTime: 'ON TIME', remarks: 'AMBASSADOR SERVICE'},
{flightNum: '671', destinationCity: 'Los Angeles Intl', schedTime: '18:02', actualTime: 'ON TIME', remarks: 'VIA PHOENIX'},
];
return this.FLIGHTS;
}
public getFlightData(): FlightInfo[] { // timing issue? web lag?
console.log(">>> getFlightData(): ");
this.http.get("http://localhost/flights.php", { responseType: 'text' }).subscribe(data => {
this.httpData = JSON.parse(data);
console.log(">>> resp = " + data.toString());
for (var f = 0; f < this.httpData.flights.length; f++) {
console.log(">>> creating element - " + this.httpData.flights[f].flightNum);
newFlight = new FlightInfo();
newFlight.flightNum = this.httpData.flights[f].flightNum;
newFlight.destinationCity = this.httpData.flights[f].destinationCity;
newFlight.schedTime = this.httpData.flights[f].schedTime;
newFlight.actualTime = this.httpData.flights[f].actualTime;
newFlight.remarks = this.httpData.flights[f].remarks;
this.FLIGHTS.push(newFlight);
}
});
// A static array assigning a series of new FlightInfo objects here can be seen
// by Angular Material, outside the .subscribe() method above. Inside, the same
// for loop causes NOTHING to happen to the this.FLIGHTS array.
return this.FLIGHTS;
}
}
第一个方法,getFlightDataLocally(),按我的预期执行——当 HTML 页面出现时,我看到了五个已定义的对象。
但是当我使用第二种方法 getFlightData() 时,结果表/数组为空。更令人困惑的是,console.log 消息表明了一个对我来说不直观的触发顺序:
控制台输出:
>>> getFlightData(): table-demo.component.ts:58
>>> FLIGHTS local = 0 fltdatahttp.service.ts:59
>>> resp = { "flights" : [
{
"flightNum" : "345",
"destinationCity" : "CHICAGO MIDWAY",
"schedTime" : "09:30",
"actualTime" : "ON TIME",
"remarks" : "AMBASSADOR SERVICE"
},
{
"flightNum" : "712",
"destinationCity" : "MILWAUKEE",
"schedTime" : "09:44",
"actualTime" : "ON TIME",
"remarks" : "AMBASSADOR SERVICE"
},
{
"flightNum" : "910",
"destinationCity" : "CHAMPAIGN/URBANA",
"schedTime" : "09:56",
"actualTime" : "ON TIME",
"remarks" : "AMBASSADOR SERVICE"
},
{
"flightNum" : "118",
"destinationCity" : "HOUSTON HOBBY",
"schedTime" : "10:00",
"actualTime" : "ON TIME",
"remarks" : "AMBASSADOR SERVICE"
},
{
"flightNum" : "627",
"destinationCity" : "MIAMI",
"schedTime" : "10:03",
"actualTime" : "ON TIME",
"remarks" : "NONSTOP"
},
...
...
}
]} fltdatahttp.service.ts:63
>>> creating element - 345
fltdatahttp.service.ts:63
>>> creating element - 712
fltdatahttp.service.ts:63
>>> creating element - 910
fltdatahttp.service.ts:63
>>> creating element - 118
fltdatahttp.service.ts:63
>>> creating element - 627
fltdatahttp.service.ts:63
...
我期望 getFlightData() 做的是返回一个包含所有 25 个 JSON 对象的数组——但它似乎所做的只是什么都不返回,而且它似乎是某种我无法解决的序列/时间问题把我的头包起来。 .subscribe 的第一个箭头函数中的 data 变量清楚地接收数据,但尝试将其保存到本地变量 this.httpData 没有奏效。
有人能解释一下什么可以成功地从 Angular 脚本调用第二个 Web 服务器,并让返回的任何数据实际保留而不是消失吗?
我这里有什么问题?
谢谢!
【问题讨论】: