Angular: Показать наложение загрузчика / счетчика с сервисом - PullRequest
0 голосов
/ 07 мая 2020

В настоящее время я работаю над проектом Angular 8, и в настоящее время я работаю над функцией, которую, как мне кажется, используют многие проекты. Я хочу отображать счетчик, когда что-то загружается в приложении, с серым фоном, чтобы вы не могли взаимодействовать с приложением во время загрузки.

Я нашел несколько примеров в Inte rnet, но большинство из них используют перехватчики, чтобы отображать наложение каждый раз, когда выполняется http-вызов. В моем случае это невозможно, поскольку некоторые HTTP-вызовы не должны блокировать использование приложения.

Итак, я черпал вдохновение из уже используемого пакета: Angular2-notifications.

  • Я создал LoaderService, используя только методы start () и end (). Их можно вызывать в любом месте приложения.
  • Я создал LoaderComponent, который я поместил в app.component. html, и отображает это наложение всякий раз, когда LoaderService сообщает об этом.

Моя основная проблема здесь - синхронизация, если у меня есть несколько запросов на загрузчик. Например, у меня есть экран с несколькими вкладками, и некоторые из них загружают собственный контент. Это не вариант ленивой загрузки, все данные загружаются при инициализации экрана. Итак, каждая из этих вкладок будет запрашивать отображение счетчика в один и тот же момент.

Мое решение прямо сейчас состоит в том, что LoaderService.start () возвращает токен, и когда вызов будет выполнен, вы должны вызвать LoadService .end (myToken), чтобы скрыть счетчик. В сервисе я храню массив всех текущих используемых токенов, и счетчик отображается, когда этот массив. Length> 0.

Код прямо здесь: LoaderService:

@Injectable()
export class LoaderService {

  private currentIndex = 0;
  private currentLoaderIds: number[] = [];

  public emitter = new Subject<boolean>();

  start(): number {
    this.currentIndex++;
    this.currentLoaderIds.push(this.currentIndex);
    this.emitter.next(true);
    return this.currentIndex;
  }

  end(id?: number): void {
    if (!id) {
      return;
    }
    this.currentLoaderIds = this.currentLoaderIds.filter(i => i !== id);
    if (this.currentLoaderIds.length === 0) {
      this.emitter.next(false);
    }
  }
}

LoaderComponent

export class LoaderComponent implements OnInit, OnDestroy {

  private show = false;
  private listener: Subscription;

  constructor(
    private loader: LoaderService
  ) { }

  ngOnInit() {
    this.listener = this.loader.emitter
      .subscribe(val => {
        this.show = val;
      });
  }

  ngOnDestroy() {
    if (this.listener) {
      this.listener.unsubscribe();
    }
  }

}

Честно говоря, это работает нормально! Моя проблема в том, что я не считаю это решение действительно элегантным. Я почти уверен, что, возможно, есть чем заняться, чтобы избежать этой системы токенов. Кроме того, я новичок в Observables и считаю, что с их помощью можно найти более элегантное решение. И поскольку я хочу улучшить свои навыки наблюдения, я бы хотел go таким образом

Так что, если вы можете помочь мне найти лучшее решение, это было бы очень полезно. Спасибо!

...