В настоящее время я работаю над проектом 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 таким образом
Так что, если вы можете помочь мне найти лучшее решение, это было бы очень полезно. Спасибо!