angular 仅在填充了 indexedDb table 时才在组件中加载数据
angular load data in component only when indexedDb table is populated
在我的服务中,我有这个:
synchronizeCitiesOnLogin() {
....
this.getCitiesFromApi().subscribe(
cities => {
cities.map((city) => {
this.addCityToIndexedDb(city);
});
}
);
}
getCitiesFromApi() {
....
return this.apiClient.get(url, { })
.pipe(
map((response: any) => response.data ),
catchError(errorRes => {
return throwError(errorRes);
})
);
}
addCitiesToIndexedDb(city) {
this.cityTable
.add(city)
.then(async () => {
const allItems: CityModel[] = await this.cityTable.toArray();
})
.catch(e => {
alert('Error: ' + (e.stack || e));
});
}
getData(): Promise<any> {
return this.getDataFromIndexedDb()
}
private async getDataFromIndexedDb() {
...
...
return mydata
}
在我的组件中:
ngOnInit() {
this.myService.getData().then(data => {
this.worldCities= data;
});
}
因为我有很多从 API 收到的数据,所以需要一些时间才能将它们全部保存在 IndexedDB 中。当我加载页面时,“水果”对象将为空,因为数据尚未保存在 IndexedDB 中......
如果我在 2-3 秒内添加一个 settimeout,它就可以工作,但肯定它应该是解决它的更好方法
有人可以帮我吗?
谢谢
可以考虑在myService
中加一个BehaviorSubject
。
private synchronized$ = new BehaviorSubject(false);
此后你需要以某种方式捕捉城市插入 indexeddb 的完成,看起来可能像
import { from } from 'rxjs';
synchronizeCitiesOnLogin() {
this.getCitiesFromApi().pipe(
switchMap((cities) => combineLatest(
cities.map(city => from(this.cityTable.add(city)))
)),
tap(() => {
this.synchronized$.next(true);
})
).subscribe()
}
然后您可以确保在访问数据之前同步数据:
getData(): Promise<any> {
return this.synchronized$.pipe(
filter(synchronized => synchronized),
first(),
switchMap(() => from(this.getDataFromIndexedDb()))
).toPromise();
}
当然可以使上面的内容更具可读性,因为我强烈建议使用 ngx-indexed-db 来完整 RxJs
,以避免在 observables 和 promise api 之间不断切换。
在我的服务中,我有这个:
synchronizeCitiesOnLogin() {
....
this.getCitiesFromApi().subscribe(
cities => {
cities.map((city) => {
this.addCityToIndexedDb(city);
});
}
);
}
getCitiesFromApi() {
....
return this.apiClient.get(url, { })
.pipe(
map((response: any) => response.data ),
catchError(errorRes => {
return throwError(errorRes);
})
);
}
addCitiesToIndexedDb(city) {
this.cityTable
.add(city)
.then(async () => {
const allItems: CityModel[] = await this.cityTable.toArray();
})
.catch(e => {
alert('Error: ' + (e.stack || e));
});
}
getData(): Promise<any> {
return this.getDataFromIndexedDb()
}
private async getDataFromIndexedDb() {
...
...
return mydata
}
在我的组件中:
ngOnInit() {
this.myService.getData().then(data => {
this.worldCities= data;
});
}
因为我有很多从 API 收到的数据,所以需要一些时间才能将它们全部保存在 IndexedDB 中。当我加载页面时,“水果”对象将为空,因为数据尚未保存在 IndexedDB 中...... 如果我在 2-3 秒内添加一个 settimeout,它就可以工作,但肯定它应该是解决它的更好方法 有人可以帮我吗? 谢谢
可以考虑在myService
中加一个BehaviorSubject
。
private synchronized$ = new BehaviorSubject(false);
此后你需要以某种方式捕捉城市插入 indexeddb 的完成,看起来可能像
import { from } from 'rxjs';
synchronizeCitiesOnLogin() {
this.getCitiesFromApi().pipe(
switchMap((cities) => combineLatest(
cities.map(city => from(this.cityTable.add(city)))
)),
tap(() => {
this.synchronized$.next(true);
})
).subscribe()
}
然后您可以确保在访问数据之前同步数据:
getData(): Promise<any> {
return this.synchronized$.pipe(
filter(synchronized => synchronized),
first(),
switchMap(() => from(this.getDataFromIndexedDb()))
).toPromise();
}
当然可以使上面的内容更具可读性,因为我强烈建议使用 ngx-indexed-db 来完整 RxJs
,以避免在 observables 和 promise api 之间不断切换。