首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >角4异步管道不工作

角4异步管道不工作
EN

Stack Overflow用户
提问于 2017-09-26 19:05:28
回答 2查看 4.4K关注 0票数 1

我正在尝试使用异步管道,但是没有显示数据。我正在记录来自服务器的数据,它在控制台中显示得很好。但由于某些原因,我无法让异步运行。

shift.service.ts

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
<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没有任何价值。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-09-26 19:19:12

在结果以异步方式出现之前,您正在解析承诺,并且承诺只解析一次。您需要返回未解决的承诺,然后等待结果的出现,然后解决您的承诺,如下所示:

代码语言:javascript
复制
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;
}

然后,在您的组件中,您使用的承诺都是错误的。您正在定义和设置超出范围的变量。异步管道为您处理所有这些。

或者更好的是,不要使用承诺,因为观察结果要好得多

服务:

代码语言:javascript
复制
// 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);
   });
}

构成部分:

代码语言:javascript
复制
// 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();

模板:

代码语言:javascript
复制
//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>
票数 0
EN

Stack Overflow用户

发布于 2017-09-26 19:15:19

我猜您在checkShiftStatus方法中从shift.service.ts返回一个未定义的值。

代码语言:javascript
复制
return Promise.resolve(this.shift);

您应该以这种方式重构您的方法:

代码语言:javascript
复制
checkShiftStatus(): Observable<Shift>{
  return this.httpClient.get<Shift>('http://localhost:8080/shift/isopen')
}

然后对shift.component.ts和shift.component.html中的数据做一些处理:

代码语言:javascript
复制
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;
  }
}
代码语言:javascript
复制
<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>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46434037

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档