使用Angular在HTTP请求中显示和隐藏加载动画。

4
我最近几天一直在尝试从AngularJS迁移到Angular。我已经有一个Web应用程序,希望通过重写它来进行练习。旧版本中的一个功能是在HTTP请求期间显示加载动画。我在Google和在线教程上搜索了如何在Angular中实现该功能,并选择了使用服务的方式。下面是代码:
spinner.service.ts
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs/Rx';

export interface ISpinnerState {
  show: boolean
}

@Injectable()
export class SpinnerService {
  private _spinnerSubject = new Subject();

  spinnerState = <Observable<ISpinnerState>>this._spinnerSubject;

  show() {
    this._spinnerSubject.next(<ISpinnerState>{ show: true });
  }

  hide() {
    this._spinnerSubject.next(<ISpinnerState>{ show: false });
  }
}

spinner.component.ts

import {Component, OnDestroy, OnInit} from '@angular/core';
import { Subscription } from 'rxjs/Rx';

import { ISpinnerState, SpinnerService } from './spinner.service';

@Component({
  selector: 'loading-spinner',
  template: `
    <div
      class="spinner">
    </div>
  `,
  styles: [`.spinner {position: absolute;left: 46%;top: 12%;background-color:black;width:50px;height:50px}`]
})

export class SpinnerComponent implements OnDestroy, OnInit {
  visible = false;

  private _spinnerStateChanged: Subscription;

  constructor(private _spinnerService: SpinnerService) { }

  ngOnInit() {
    this._spinnerStateChanged = this._spinnerService.spinnerState
      .subscribe((state: ISpinnerState) => this.visible = state.show);
  }

  ngOnDestroy() {
    this._spinnerStateChanged.unsubscribe();
  }
}

目前,它只是一个黑色的正方形,以便我可以测试它。之后,我将添加适当的加载图标。这是另一个服务,在HTTP请求期间调用它。

apartment.service.ts

....other stuff

@Injectable()
export class ApartmentService {

  constructor(
    private _http: Http,
    private _spinnerService: SpinnerService
  ) { }

getApartments() {
    this._spinnerService.show();
    return this._http.get(API + 'apartments')
      .map((response: Response) => <Apartment[]>response.json().apartments)
      //.catch(this._exceptionService.catchBadResponse)
      .finally(() => this._spinnerService.hide());
  }

}

问题在于旋转器一直可见,而不仅仅是在加载过程中。我不知道我做错了什么。有什么想法吗?

1
我认为 spinnerState = <Observable<ISpinnerState>>this._spinnerSubject; 应该改成 spinnerState = <Observable<ISpinnerState>>this._spinnerSubject.asObservable(); - Günter Zöchbauer
你提供服务的地方在哪里? - Günter Zöchbauer
你在哪里使用 visible 来显示/隐藏旋转器? - Günter Zöchbauer
如果我更改代码,我会在此处出现错误:[ts] Property 'asObservable' does not exist on type 'Subject<{}>'. 你说的“我提供服务的地方”是什么意思? - Tasos
很奇怪,我确信它应该可以正常工作。https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/asobservable.md - Günter Zöchbauer
1个回答

4

我认为您错过了根据visible状态显示/隐藏绑定的部分:

<div *ngIf="visible"
  class="spinner">
</div>

我导入了HostBinding,并在组件上方添加了“visible=false”,但仍然出现相同的行为。旋转器始终可见。 - Tasos
天啊...我简直不敢相信我错过了 *ngIf...我花了两天时间试图找出代码的问题,却完全没有检查那两行代码 :P 现在它可以工作了 :) - Tasos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接