角度4异步管道无法正常工作 [英] angular 4 async pipe is not working

查看:56
本文介绍了角度4异步管道无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用异步管道,但没有显示任何数据.我正在记录来自服务器的数据,它在控制台中显示良好.但是由于某种原因,我无法使异步工作.

I'm trying to use async pipe but there is no data being displayed. I'm logging the data that is coming from the server and it shows up fine in the console. But for some reason I can't get the async to work.

shift.service.ts

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

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

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没有任何价值.

The buttons don't even show up even though the service is providing with the value of true. I do get the div to show up but there is no value for shiftLive.active, or the shiftLive.totalNumberOfTicketsSold.

推荐答案

您要在结果异步生成之前解决承诺,并且承诺只能解决一次.您需要返回未解决的承诺,并等待结果输入,然后解决您的承诺,如下所示:

You're resolving the promise before the result comes in asynchronously and promises only resolve once. You need to return the unresolved promise and wait for the result to come in and then resolve your promise, like this:

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;
}

然后,您对诺言的使用在您的组件中都是错误的.您正在定义和设置范围之外的变量.异步管道会为您处理所有这些事情.

And then your use of promises is all wrong in your component. You're defining and setting variables that are outside the scope. The async pipe handles all of this for you.

或者更好,因为可观察性更好,所以根本不使用承诺

or better yet, don't use the promise at all since observables are way better

服务:

// 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>

这篇关于角度4异步管道无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆