angular - 使用 rxjs 的角度加载服务
问题描述
我的 Angular 应用程序包含一些服务,这些服务需要在显示应用程序组件之前初始化数据异步(pe 从 API 和 i18n 通过 ng-translate 加载初始数据)。在中央服务中,我想观察所有异步任务并提供一个 Observable 来通知其他组件和服务系统已准备好(并隐藏加载动画)。
我的第一个尝试是:
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { combineLatest } from 'rxjs/observable/combineLatest';
@Injectable({
providedIn: 'root',
})
export class LoadingService {
private tokens: Observable<boolean>[] = [];
public tokenObservable: Observable<boolean[]>;
constructor() {
this.tokenObservable = combineLatest(this.tokens);
}
public registerLoadingToken(token: Observable<boolean>): void {
this.tokens.push(token);
}
}
所有初始化服务都必须在这个 LoadingService 中注册一个 Observable。但我认为我遇到了时间问题。该计划是:
- LoadingService 提供 Observable,每个 Component 都可以订阅
- 所有的 asyc 服务都会注册他们的 Observable
- 如果每个异步服务都至少触发了一次,LoadingService 会触发其 Observable
但是我怎样才能正确设置时间呢?
如果我在构造函数中使用 combineLatest,则不会注册任何令牌。
如果我使用 combineLatest 异步(如:)setTimeout({}, 0)
,则可观察到的公共令牌为空。
你对我有什么想法吗?
解决方案
好的:这有效:
加载服务:
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { combineLatest } from 'rxjs/observable/combineLatest';
@Injectable({
providedIn: 'root',
})
export class LoadingService {
private tokens: Observable<any>[] = [];
private internalSubject = new Subject<any>();
public tokenObservable: Observable<any>;
constructor() {
this.tokenObservable = this.internalSubject.asObservable();
}
// call in the OnInit of app.component.ts
public listenToTokens(): void {
combineLatest(this.tokens).subscribe(_ => this.internalSubject.next(true));
}
public registerLoadingToken(token: Observable<any>): void {
this.tokens.push(token);
}
}
我的异步服务:
public awaiter: Subject<any>;
constructor(
apiService: ApiService,
private navigationService: NavigationService,
private translationService: TranslateService,
loadingService: LoadingService) {
loadingService.registerLoadingToken(this.awaiter);
apiService.get<api.Field[]>('FormMetadata').subscribe(_ => {
this.setMetadata(_);
this.awaiter.next(true);
}, _ => this.handleError(_));
}
和 appComponent.ts:
ngOnInit(): void {
this.loadingService.listenToTokens();
}
然后我可以在我的 MainComponent 上订阅它:
constructor(loadingService: LoadingService) {
loadingService.tokenObservable.subscribe(_ => this.state = 'none');
}
推荐阅读
- linux - 什么是 .pivot_root 文件?
- visual-studio-code - 如何构建和运行 VSCode 扩展拾色器?
- c# - 如何使用 fluent api 设置手机号码和邮政编码的最大长度?
- c# - 如何对依赖基类的方法进行单元测试?
- linux - 如何更改 Kubernetes 的版本
- javascript - 在 JavaScript 中下载之前捕获 PNG 文件
- php - 如何从 laravel 获取 db 中列的平均值
- angular - 为什么我的 Firebase 部署的 Web 应用程序无法正常工作?
- .net - 我在 .Net MVC 中创建了 HighStockChart Graph,但 Y 轴标签出现在右侧,但我希望它出现在左侧
- android - Android TV:从 ListRowPresenter 中的项目中删除阴影