Angular 8 - HttpClient GET 一个复杂的 JSON 对象并填充一个 html table
Angular 8 - HttpClient GET a complex JSON object and fill an html table
我正在使用 Angular 8,并且正在查询端点以获取对象。当我通过高级 REST 客户端调用它时,我得到以下 returned JSON:
获取:http://localhost:8090/curso_conductor/
Returns:
{
"dato": [{
"ID_CURSO_CONDUCTOR": 1,
"F_INICIO": "2019-09-19T05:00:00.000+0000",
"F_FIN": "2019-12-20T05:00:00.000+0000",
"ESTADO": "1",
"CARNET_C": "l584f",
"F_CADUCIDAD": "2022-06-20T05:00:00.000+0000",
"F_EMISION": "2017-06-20T05:00:00.000+0000",
"ID_CURSO": 1,
"ID_PERSONA": 3
},
{
"ID_CURSO_CONDUCTOR": 2,
"F_INICIO": "2019-08-20T05:00:00.000+0000",
"F_FIN": "2019-12-20T05:00:00.000+0000",
"ESTADO": "1",
"CARNET_C": "8574h",
"F_CADUCIDAD": "2023-04-05T05:00:00.000+0000",
"F_EMISION": "2017-04-08T05:00:00.000+0000",
"ID_CURSO": 1,
"ID_PERSONA": 5
},
{
"ID_CURSO_CONDUCTOR": 3,
"F_INICIO": "2019-10-09T05:00:00.000+0000",
"F_FIN": "2019-12-10T05:00:00.000+0000",
"ESTADO": "1",
"CARNET_C": "2685f",
"F_CADUCIDAD": "2022-08-10T05:00:00.000+0000",
"F_EMISION": "2017-08-09T05:00:00.000+0000",
"ID_CURSO": 1,
"ID_PERSONA": 6
}
],
}
在 Angular 8 中,我有一个服务,我想在其中对将 return 上述 JSON.[=25= 的端点进行 http 调用]
getCursoConductor(): Observable<Curso_Conductor[]>{
return this.http.get<Curso_Conductor[]>(this.curso_conductores).pipe();
}
如您所见,结果需要放入 Curso_Conductor
对象中。
我的模型是这样的:
export class Curso_Conductor {
dato: Dato[];
}
export class Dato {
ID_CURSO_CONDUCTOR: number;
F_INICIO: string;
F_FIN: string;
ESTADO: string;
CARNET_C: string;
F_CADUCIDAD: string;
F_EMISION: string;
ID_CURSO: number;
ID_PERSONA: number;
}
我的问题是如何将数据放入Curso_conductorComponent.html
?
这是我的 component.html
:
<table class="table table-hover">
<thead>
<tr>
<th>ID</th>
<th>FECHA INICIO</th>
<th>FECHA FIN</th>
<th>ESTADO</th>
<th>Nro CARNET</th>
<th>FECHA CADUCIDAD</th>
<th>FECHA EMISION</th>
<th>IDCURSO</th>
<th>IDPERSONA</th>
<th colspan="2">OPCION</th>
</tr>
</thead>
<tbody>
<tr *ngIf="curso_conductoresObservable | async as curso_conductores else empty">
<tr *ngFor="let curso_conductor of curso_conductores">
<td>{{curso_conductor.id_curso_conductor}}</td>
<td>{{curso_conductor.f_inicio}}</td>
<td>{{curso_conductor.f_fin}}</td>
<td>{{curso_conductor.estado}}</td>
<td>{{curso_conductor.carnet_c}}</td>
<td>{{curso_conductor.f_caducidad}}</td>
<td>{{curso_conductor.f_emision}}</td>
<td>{{curso_conductor.id_curso}}</td>
<td>{{curso_conductor.id_persona}}</td>
<td><button class="btn btn-warning" (click)="Editar(curso_conductor)">Editar</button></td>
<td><button class="btn btn-danger" (click)="Eliminar(curso_conductor)">Eliminar</button></td>
</tr>
</tbody>
</table>
还有我的 component.ts
:
curso_conductores: Curso_Conductor[];
constructor(private service: ServiceService, private router: Router) { }
@Input() nombre = '';
ngOnInit() {
this.service.getCursoConductor()
.subscribe(data => {this.curso_conductores=data });
}
我收到这个错误:
Cannot find a differ supporting object
'[object Object]' of type 'object'. NgFor only supports binding to
Iterables such as Arrays.
您确定 return 类型是 Curso_Conductor[] 吗?好像是Curso_Conductor。
试试这个,
getCursoConductor(): Observable<Curso_Conductor>{
return this.http.get<Curso_Conductor>(this.curso_conductores).pipe();
}
...
curso_conductore: Curso_Conductor;
constructor(private service: ServiceService, private router: Router) { }
@Input() nombre = '';
ngOnInit() {
this.service.getCursoConductor().subscribe(data => {this.curso_conductore=data });
}
并在 html
...
<tr *ngFor="let d of curso_conductore.dato.dato">
<td>{{d.id_curso_conductor}}</td>
<td>{{d.f_inicio}}</td>
...
您的实施存在一些问题。
您从 API 获得的数组出现在 dato
属性 上。理想情况下,您应该为此创建一个界面:
export interface ApiResponse {
dato: Curso_Conductor[];
}
export interface Curso_Conductor {
ID_CURSO_CONDUCTOR: number;
F_INICIO: string;
F_FIN: string;
ESTADO: string;
CARNET_C: string;
F_CADUCIDAD: string;
F_EMISION: string;
ID_CURSO: number;
ID_PERSONA: number;
}
然后您必须更新您的服务以反映您期望的数据类型。我也在更改服务的名称,因为 ServiceService
根本没有意义:
import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { Observable } from "rxjs";
import { ApiResponse } from "./models/conductor.model";
@Injectable()
export class DataService {
curso_conductores = "assets/data.json";
constructor(private http: HttpClient) {}
getCursoConductor(): Observable<ApiResponse> {
return this.http.get<ApiResponse>(this.curso_conductores);
}
}
您正在 subscribe
访问组件中的 Observable
并且您还在使用 async
管道。它会自动为您展开。因此,请坚持在模板中使用 async
管道。这也是推荐的方式:
import { Component } from "@angular/core";
import { Curso_Conductor, ApiResponse } from "./models/conductors.model";
import { DataService } from "./data.service";
import { Observable } from "rxjs";
import { map } from "rxjs/operators";
@Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
curso_conductores$: Observable<Array<Curso_Conductor>>;
constructor(private service: DataService) {}
ngOnInit() {
this.curso_conductores$ = this.service.getCursoConductor()
.pipe(
map((apiResponse: ApiResponse) => apiResponse.dato)
);
}
}
最后,对象字段都是大写的,但您在模板中将它们用作小写。这也需要修复:
<table class="table table-hover" border="1">
<thead>
<tr>
<th>ID</th>
<th>FECHA INICIO</th>
<th>FECHA FIN</th>
<th>ESTADO</th>
<th>Nro CARNET</th>
<th>FECHA CADUCIDAD</th>
<th>FECHA EMISION</th>
<th>IDCURSO</th>
<th>IDPERSONA</th>
<th colspan="2">OPCION</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let curso_conductor of (curso_conductores$ | async) as curso_conductores">
<td>{{curso_conductor.ID_CURSO_CONDUCTOR}}</td>
<td>{{curso_conductor.F_INICIO}}</td>
<td>{{curso_conductor.F_FIN}}</td>
<td>{{curso_conductor.ESTADO}}</td>
<td>{{curso_conductor.CARNET_C}}</td>
<td>{{curso_conductor.F_CADUCIDAD}}</td>
<td>{{curso_conductor.F_EMISION}}</td>
<td>{{curso_conductor.ID_CURSO}}</td>
<td>{{curso_conductor.ID_PERSONA}}</td>
<td><button class="btn btn-warning" (click)="Editar(curso_conductor)">Editar</button></td>
<td><button class="btn btn-danger" (click)="Eliminar(curso_conductor)">Eliminar</button></td>
</tr>
</tbody>
</table>
希望这能帮您解决这个问题。
Here's a Working Sample StackBlitz for your ref.
我正在使用 Angular 8,并且正在查询端点以获取对象。当我通过高级 REST 客户端调用它时,我得到以下 returned JSON:
获取:http://localhost:8090/curso_conductor/
Returns:
{
"dato": [{
"ID_CURSO_CONDUCTOR": 1,
"F_INICIO": "2019-09-19T05:00:00.000+0000",
"F_FIN": "2019-12-20T05:00:00.000+0000",
"ESTADO": "1",
"CARNET_C": "l584f",
"F_CADUCIDAD": "2022-06-20T05:00:00.000+0000",
"F_EMISION": "2017-06-20T05:00:00.000+0000",
"ID_CURSO": 1,
"ID_PERSONA": 3
},
{
"ID_CURSO_CONDUCTOR": 2,
"F_INICIO": "2019-08-20T05:00:00.000+0000",
"F_FIN": "2019-12-20T05:00:00.000+0000",
"ESTADO": "1",
"CARNET_C": "8574h",
"F_CADUCIDAD": "2023-04-05T05:00:00.000+0000",
"F_EMISION": "2017-04-08T05:00:00.000+0000",
"ID_CURSO": 1,
"ID_PERSONA": 5
},
{
"ID_CURSO_CONDUCTOR": 3,
"F_INICIO": "2019-10-09T05:00:00.000+0000",
"F_FIN": "2019-12-10T05:00:00.000+0000",
"ESTADO": "1",
"CARNET_C": "2685f",
"F_CADUCIDAD": "2022-08-10T05:00:00.000+0000",
"F_EMISION": "2017-08-09T05:00:00.000+0000",
"ID_CURSO": 1,
"ID_PERSONA": 6
}
],
}
在 Angular 8 中,我有一个服务,我想在其中对将 return 上述 JSON.[=25= 的端点进行 http 调用]
getCursoConductor(): Observable<Curso_Conductor[]>{
return this.http.get<Curso_Conductor[]>(this.curso_conductores).pipe();
}
如您所见,结果需要放入 Curso_Conductor
对象中。
我的模型是这样的:
export class Curso_Conductor {
dato: Dato[];
}
export class Dato {
ID_CURSO_CONDUCTOR: number;
F_INICIO: string;
F_FIN: string;
ESTADO: string;
CARNET_C: string;
F_CADUCIDAD: string;
F_EMISION: string;
ID_CURSO: number;
ID_PERSONA: number;
}
我的问题是如何将数据放入Curso_conductorComponent.html
?
这是我的 component.html
:
<table class="table table-hover">
<thead>
<tr>
<th>ID</th>
<th>FECHA INICIO</th>
<th>FECHA FIN</th>
<th>ESTADO</th>
<th>Nro CARNET</th>
<th>FECHA CADUCIDAD</th>
<th>FECHA EMISION</th>
<th>IDCURSO</th>
<th>IDPERSONA</th>
<th colspan="2">OPCION</th>
</tr>
</thead>
<tbody>
<tr *ngIf="curso_conductoresObservable | async as curso_conductores else empty">
<tr *ngFor="let curso_conductor of curso_conductores">
<td>{{curso_conductor.id_curso_conductor}}</td>
<td>{{curso_conductor.f_inicio}}</td>
<td>{{curso_conductor.f_fin}}</td>
<td>{{curso_conductor.estado}}</td>
<td>{{curso_conductor.carnet_c}}</td>
<td>{{curso_conductor.f_caducidad}}</td>
<td>{{curso_conductor.f_emision}}</td>
<td>{{curso_conductor.id_curso}}</td>
<td>{{curso_conductor.id_persona}}</td>
<td><button class="btn btn-warning" (click)="Editar(curso_conductor)">Editar</button></td>
<td><button class="btn btn-danger" (click)="Eliminar(curso_conductor)">Eliminar</button></td>
</tr>
</tbody>
</table>
还有我的 component.ts
:
curso_conductores: Curso_Conductor[];
constructor(private service: ServiceService, private router: Router) { }
@Input() nombre = '';
ngOnInit() {
this.service.getCursoConductor()
.subscribe(data => {this.curso_conductores=data });
}
我收到这个错误:
Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
您确定 return 类型是 Curso_Conductor[] 吗?好像是Curso_Conductor。 试试这个,
getCursoConductor(): Observable<Curso_Conductor>{
return this.http.get<Curso_Conductor>(this.curso_conductores).pipe();
}
...
curso_conductore: Curso_Conductor;
constructor(private service: ServiceService, private router: Router) { }
@Input() nombre = '';
ngOnInit() {
this.service.getCursoConductor().subscribe(data => {this.curso_conductore=data });
}
并在 html
...
<tr *ngFor="let d of curso_conductore.dato.dato">
<td>{{d.id_curso_conductor}}</td>
<td>{{d.f_inicio}}</td>
...
您的实施存在一些问题。
您从 API 获得的数组出现在
dato
属性 上。理想情况下,您应该为此创建一个界面:export interface ApiResponse { dato: Curso_Conductor[]; } export interface Curso_Conductor { ID_CURSO_CONDUCTOR: number; F_INICIO: string; F_FIN: string; ESTADO: string; CARNET_C: string; F_CADUCIDAD: string; F_EMISION: string; ID_CURSO: number; ID_PERSONA: number; }
然后您必须更新您的服务以反映您期望的数据类型。我也在更改服务的名称,因为
ServiceService
根本没有意义:import { Injectable } from "@angular/core"; import { HttpClient } from "@angular/common/http"; import { Observable } from "rxjs"; import { ApiResponse } from "./models/conductor.model"; @Injectable() export class DataService { curso_conductores = "assets/data.json"; constructor(private http: HttpClient) {} getCursoConductor(): Observable<ApiResponse> { return this.http.get<ApiResponse>(this.curso_conductores); } }
您正在
subscribe
访问组件中的Observable
并且您还在使用async
管道。它会自动为您展开。因此,请坚持在模板中使用async
管道。这也是推荐的方式:import { Component } from "@angular/core"; import { Curso_Conductor, ApiResponse } from "./models/conductors.model"; import { DataService } from "./data.service"; import { Observable } from "rxjs"; import { map } from "rxjs/operators"; @Component({ selector: "my-app", templateUrl: "./app.component.html", styleUrls: ["./app.component.css"] }) export class AppComponent { curso_conductores$: Observable<Array<Curso_Conductor>>; constructor(private service: DataService) {} ngOnInit() { this.curso_conductores$ = this.service.getCursoConductor() .pipe( map((apiResponse: ApiResponse) => apiResponse.dato) ); } }
最后,对象字段都是大写的,但您在模板中将它们用作小写。这也需要修复:
<table class="table table-hover" border="1">
<thead>
<tr>
<th>ID</th>
<th>FECHA INICIO</th>
<th>FECHA FIN</th>
<th>ESTADO</th>
<th>Nro CARNET</th>
<th>FECHA CADUCIDAD</th>
<th>FECHA EMISION</th>
<th>IDCURSO</th>
<th>IDPERSONA</th>
<th colspan="2">OPCION</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let curso_conductor of (curso_conductores$ | async) as curso_conductores">
<td>{{curso_conductor.ID_CURSO_CONDUCTOR}}</td>
<td>{{curso_conductor.F_INICIO}}</td>
<td>{{curso_conductor.F_FIN}}</td>
<td>{{curso_conductor.ESTADO}}</td>
<td>{{curso_conductor.CARNET_C}}</td>
<td>{{curso_conductor.F_CADUCIDAD}}</td>
<td>{{curso_conductor.F_EMISION}}</td>
<td>{{curso_conductor.ID_CURSO}}</td>
<td>{{curso_conductor.ID_PERSONA}}</td>
<td><button class="btn btn-warning" (click)="Editar(curso_conductor)">Editar</button></td>
<td><button class="btn btn-danger" (click)="Eliminar(curso_conductor)">Eliminar</button></td>
</tr>
</tbody>
</table>
希望这能帮您解决这个问题。
Here's a Working Sample StackBlitz for your ref.