因此,我遇到了这个问题,我一直想把头缠起来:我有这一系列的边栏项目,需要从两个来源合并。第一个来源将在前端代码库中,并且与项目的视觉方面有关:图标类,URL等,我们将使用前端代码库进行维护。第二个来源是数据库,因为我需要在数据库中保留一些信息以便提供一种功能,其中可以将这些项目中的任何一项标记为已完成,并且它们的状态应持久。
项目如下:
export interface Item {
id?: number;
name: string;
label: string;
completed?: boolean;
iconClass: string;
url: string;
}
我在前端维护标签,iconClass和url,并从数据库中获取ID并完成操作,然后按名称“加入”它们,这两个来源中都存在。
这是我的服务摘要:
export class SidebarService {
someNecessaryId: number;
// I keep the front-end related items here for the moment
items: Item[] = [...];
constructor(
private http: HttpClient
) { }
async init() {
const url = `${baseUrl}/${this.someNecessaryId}/sidebar-items`;
const itemsDb = await this.http.get(url).toPromise();
if (itemsDb instanceof Array && itemsDb.length) {
// Here I basically merge the two sources together
this.items = this.items.map(item => {
const found = itemsDb.filter(itemDb => itemDb.name === item.name)[0];
return {...item, ...found};
});
}
}
mark(item: Item) {
const actualItem = this.items.filter(fItem => fItem.name === item.name)[0];
const url = `${baseUrl}/${this.someNecessaryId}/sidebar-items/${item.id}/mark`;
this.http.post(url, item)
.subscribe(res => {
if (res instanceof Item) {
actualItem.completed = res.completed;
}
});
}
}
在使用组件中的该服务,订阅结果并注意到各种问题之后,我决定尝试异步等待,这样我就知道组件中的所有信息都是立即可用的。这是一个好选择吗?
编辑:我可能遗漏了一些重要的细节。绘制大图:
到目前为止,我看到的唯一可行的选择是使用APP_INITIALIZER来确保所有这些地方都可以使用全部信息。
最新编辑:据我所知,我需要这些物品的某种形式的单一事实来源,以便它们根据标记/未标记来更新其状态。到目前为止,仅使用async + await即可。
答案 0 :(得分:-1)
我建议在这里使用Observables,async / await也正在等待,但是使您的代码可读。
此外,您还可以在代码中制作作为地图保存在本地的项目,这样读取速度更快,并且可以使用键/值对作为项目名称,将值作为项目值来获取它们。 {{name: {item} }
}
您可以使用异步管道将可观察对象直接绑定到模板,如下所示
export class SidebarService {
someNecessaryId: number;
// I keep the front-end related items here for the moment
itemsMap: { [key: tsring]: Item } = {}; // keep an Hashmap or object dictionary for faster reads
items$: Observable<Item[]>;
constructor(
private http: HttpClient
) { }
async init() {
const url = `${baseUrl}/${this.someNecessaryId}/sidebar-items`;
this.items$ = this.http.get(url)
.pipe(
map(response => response.map(item => ({
...item, ...(this.itemsMap[item.name] || {})
})))
);
}
getItems () {
return this.items$;
}
}
从模板
<div *ngFor="let item of items$ | async">
<!-- do something with item in this for loop -->
来自(指令/组件).ts
items = [];
constructor (private service: SidebarService) {
this.service.init();
}
getData() {
this.service.getItems().subscribe(items => {
this.items = items;
})
}