我正在尝试使用异步管道,但是没有显示数据。我正在记录来自服务器的数据,它在控制台中显示得很好。但由于某些原因,我无法让异步运行。
shift.service.ts
import { Injectable } from '@angular/core';
import { Shift } from '../shift/shift';
import { HttpClient } from '@angular/common/http';
@Injectable()
export class ShiftService {
constructor(private shift:Shift, private httpClient:HttpClient
) { this.checkShiftStatus();}
checkShiftStatus():Promise<Shift>{
this.httpClient.get<Shift>('http://localhost:8080/shift/isopen')
.subscribe((data) => {
this.shift = data;
console.log(this.shift);
},
error => {
console.error('Something went wrong while trying to check the shift!');
});
return Promise.resolve(this.shift);
}
}shift.component.ts
import { Component, OnInit } from '@angular/core';
import { Shift } from './shift';
import { ShiftService } from '../services/shift.service';
@Component({
selector: 'app-shift',
templateUrl: './shift.component.html',
styleUrls: ['./shift.component.css']
})
export class ShiftComponent implements OnInit {
isShiftOpen:Promise<boolean>;
shiftLive:Promise<Shift>;
constructor(private shiftService: ShiftService, public shift:Shift) { }
ngOnInit() {
this.isShiftOpen = this.getShift().then(shift => this.shift.active = shift.active);
this.shiftLive = this.shiftService.checkShiftStatus();
}
getShift(){
return this.shiftService.checkShiftStatus().then(shift => this.shift = shift);
}
}shift.component.html
<md-grid-list *ngIf="isShiftOpen | async" cols="2" rowHeight="100px">
<md-grid-tile>
<button md-raised-button [disabled]='isShiftOpen' color="primary">Open Shift</button>
<button md-raised-button [disabled]='!isShiftOpen' color="warn">Close Shift</button>
</md-grid-tile>
</md-grid-list>
<md-card class="card">
<md-card-title>
Shift Stats:
</md-card-title>
<md-card-content>
</md-card-content>
</md-card>
<!-- <div *ngIf="(shiftLive | async)?.notnull; else loading"> -->
<div *ngIf="shiftLive | async">
<p> Shift status: {{ shiftLive.active }} </p>
<p> Tickets Sold: {{ shiftLive.totalNumberOfTicketsSold }} </p>
</div>
<ng-template #loading>Loading Data...</ng-template>即使服务提供的值为true,按钮也不会出现。我确实让div显示出来,但是shiftLive.active或shiftLive.totalNumberOfTicketsSold没有任何价值。
发布于 2017-09-26 19:19:12
在结果以异步方式出现之前,您正在解析承诺,并且承诺只解析一次。您需要返回未解决的承诺,然后等待结果的出现,然后解决您的承诺,如下所示:
checkShiftStatus():Promise<Shift>{
let promise = new Promise<Shift>();
this.httpClient.get<Shift>('http://localhost:8080/shift/isopen')
.subscribe((data) => {
this.shift = data;
promise.resolve(this.shift);
console.log(this.shift);
},
error => {
console.error('Something went wrong while trying to check the shift!');
});
return promise;
}然后,在您的组件中,您使用的承诺都是错误的。您正在定义和设置超出范围的变量。异步管道为您处理所有这些。
或者更好的是,不要使用承诺,因为观察结果要好得多
服务:
// just return the observable stream and don't subscribe, let async handle your subscriptions
checkShiftStatus():Observable<Shift>{
return this.httpClient.get<Shift>('http://localhost:8080/shift/isopen')
.do((data) => {
// you really shouldn't do this. statefulness like this is a sign of bad design
this.shift = data;
console.log(this.shift);
}).catch(err => {
console.log('make sure to handle this error');
Observable.throw(err);
});
}构成部分:
// only set this once so that we don't make the same http call over and over, we have all the data we need here (the $ syntax is standard for denoting an observable)
this.shiftLive$ = this.shiftService.checkShiftStatus();模板:
//only use async once to avoid multiple subscriptions, and declare it "as" whatever you want, and then you have access to it throughout the template, you can still use your loading template as you want.
<ng-container *ngIf="shiftLive$ | async as shiftLive; else loading">
<md-grid-list *ngIf="shiftLive.active" cols="2" rowHeight="100px">
<md-grid-tile>
<button md-raised-button [disabled]='shiftLive.active' color="primary">Open Shift</button>
<button md-raised-button [disabled]='!shiftLive.active' color="warn">Close Shift</button>
</md-grid-tile>
</md-grid-list>
<md-card class="card">
<md-card-title>
Shift Stats:
</md-card-title>
<md-card-content>
</md-card-content>
</md-card>
<div>
<p> Shift status: {{ shiftLive.active }} </p>
<p> Tickets Sold: {{ shiftLive.totalNumberOfTicketsSold }} </p>
</div>
<ng-template #loading>Loading Data...</ng-template>
</ng-container>发布于 2017-09-26 19:15:19
我猜您在checkShiftStatus方法中从shift.service.ts返回一个未定义的值。
return Promise.resolve(this.shift);您应该以这种方式重构您的方法:
checkShiftStatus(): Observable<Shift>{
return this.httpClient.get<Shift>('http://localhost:8080/shift/isopen')
}然后对shift.component.ts和shift.component.html中的数据做一些处理:
export class ShiftComponent implements OnInit {
shift: any;
constructor(private shiftService: ShiftService, public shift:Shift) { }
ngOnInit() {
this.getShift();
}
getShift(): void {
this.shiftService.checkShiftStatus()
.subscribe(shift => this.shift = shift);
}
isActive(): boolean {
return this.shift && this.shift.active;
}
ticketsSold(): number {
return this.shift ? this.shift.totalNumberOfTicketsSold : 0;
}
}<md-grid-list *ngIf="isActive()" cols="2" rowHeight="100px">
<md-grid-tile>
<button md-raised-button [disabled]='isActive()' color="primary">Open Shift</button>
<button md-raised-button [disabled]='!isActive()' color="warn">Close Shift</button>
</md-grid-tile>
</md-grid-list>
<md-card class="card">
<md-card-title>
Shift Stats:
</md-card-title>
<md-card-content>
</md-card-content>
</md-card>
<!-- <div *ngIf="shift?.notnull; else loading"> -->
<div *ngIf="shift">
<p> Shift status: {{ isActive() }} </p>
<p> Tickets Sold: {{ ticketsSold() }} </p>
</div>
<ng-template #loading>Loading Data...</ng-template>https://stackoverflow.com/questions/46434037
复制相似问题