Отображение счетчика во время HTTP-запросов в Angular7 - PullRequest
2 голосов
/ 15 апреля 2019

Я пытаюсь показать спиннер во время HTTP-запросов приложения на Angular 7. Я создал класс HttpInterceptor, сервис загрузчика и компонент загрузчика, а также Subject, представляющий состояние счетчика (показан или скрыт). Однако существует проблема между службой загрузчика и компонентом загрузчика

Кажется, что HttpInterceptor работает нормально, так как консоль выводит состояния true и false (код ниже), однако, похоже, проблема с сервисом загрузчика и компонентом загрузчика. Я использовал директиву ngIf, чтобы показать или скрыть счетчик в соответствии с состоянием субъекта.

LoaderService:

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class LoaderService {

  isLoading = new Subject<boolean>();

  show() {
    console.log('true');
    this.isLoading.next(true);
  }

  hide() {
    console.log('false');
    this.isLoading.next(false);
  }

  constructor() { }
}

LoaderComponent

import { Component, OnInit } from '@angular/core';
import {LoaderService} from '../loader.service';
import { Subject } from 'rxjs';

@Component({
  selector: 'app-loader',
  templateUrl: './loader.component.html',
  styleUrls: ['./loader.component.css']
})
export class LoaderComponent implements OnInit {

  isLoading: Subject<boolean> = this.loaderService.isLoading;

  constructor(private loaderService: LoaderService) { }

  ngOnInit() {
  }

}
<div *ngIf="isLoading | async " class="d-flex justify-content-center">
  <div class="spinner-border" role="status">
    <span class="sr-only">Loading...</span>
  </div>
</div>

В настоящее время счетчик не отображается или не скрывается вообще. Я получаю «true» в консоли, когда начинается загрузка, и «false», когда она заканчивается. Я включил селектор загрузчика в файл app.component.html. Это должно работать правильно. Я сделал что-то не так?

Ответы [ 2 ]

1 голос
/ 15 апреля 2019

Создание HttpInterceptor, которое может выдавать логическое состояние HTTP-запросов, очень сложно.Может быть несколько параллельных запросов, происходящих в одно и то же время, и это не так просто, как отправка true / false для каждого HttpRequest.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *} * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 100 '* * 100. *отслеживать количество одновременных запросов.

Вот перехватчик, который я использую.Он выдает истину только при запуске нового запроса и только ложь, когда все запросы завершены.

import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {Injectable} from '@angular/core';
import {Observable, Subject} from 'rxjs';
import {distinctUntilChanged, finalize, map} from 'rxjs/operators';

class BusySubject extends Subject<number> {
    private _previous: number = 0;

    public next(value: number) {
        this._previous += value;
        if (this._previous < 0) {
            throw new Error('unexpected negative value');
        }
        return super.next(this._previous);
    }
}

@Injectable()
export class BusyInterceptor implements HttpInterceptor {

    private _requests: BusySubject = new BusySubject();

    public get busy(): Observable<boolean> {
        return this._requests.pipe(
            map((requests: number) => Boolean(requests)),
            distinctUntilChanged(),
        );
    }

    public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        this._requests.next(1);
        return next.handle(req).pipe(finalize(() => this._requests.next(-1)));
    }
}

ps Это можно правильно сделать с помощью оператора scan (), но у меня нету меня было время обновить код.

1 голос
/ 15 апреля 2019

Вы должны использовать BehaviourSubject вместо Subject.Subject выдает значения только при вызове next() - если компонент инициализируется после того, как служба отправила значение, тогда ничего не будет получено.

BehaviourSubject обходит это, запоминая последнее переданное значение,Когда ваш шаблон подписывается, он может получить последнее значение и выполнить его сравнение.

...