angular - Angular - 如何正确使用服务、HttpClient 和 Observables 在我的应用程序周围传递对象数组
问题描述
我一直在努力理解这一点,很多例子都在谈论 Observables 或 HttpClient 但不是两者都在一起(至少不是我的想法)。
我有一组来自数据库的类别。这些类别有一些属性,并在我的应用程序的几个不同组件中使用。
export class Category {
public Id: string = null;
public Name: string = null;
public Order: number = null;
}
我有一个角度服务,它调用后端来获取类别列表。一些组件具有创建新类别的功能。在这种情况下,我希望初始列表的所有订阅者都使用新类别进行更新。
export class CategoryService {
constructor(private httpClient: HttpClient) {
}
public getCategories(): Observable<Category[]> {
return this.httpClient.get<Category[]>('/api/CategoryAdmin/GetCategories');
}
public addCategory(newCategory: Category) {
this.httpClient.post('/api/CategoryAdmin/AddCategory', newCategory).subscribe((result: Category) => {
// what to do here?
}, error => console.error(error));
}
}
在上面的示例中,我看不出我将如何做到这一点,因此 getCategories() 的初始订阅者将收到已添加的新类别。我想我需要将类别数组存储在 CategoryService 中,然后让每个订阅者订阅它。但是,我很难理解如何正确地做到这一点。我研究了主题,我认为这可能是这样做的方法,但这样做的方法又一次让我失望了。
有人会提供一个例子或指出我正确的方向吗?
更新:根据下面的答案,我最终将我的代码更新为以下内容。我已经粘贴了整个内容,因为我认为它可以帮助人们更好地理解。
export class CategoryService {
constructor(private httpClient: HttpClient) {
}
private _categories = new BehaviorSubject<CommandCategory[]>([]);
private categories: CommandCategory[] = [];
private loading: boolean = false;
public get(): Observable<CommandCategory[]> {
this.load();
return this._categories.asObservable();
}
public load() {
if (this.categories.length === 0 && !this.loading) {
this.loading = true;
this.httpClient.get<CommandCategory[]>('/api/CategoryAdmin/GetCategories').subscribe((data: CommandCategory[]) => {
this.loading = false;
this.categories = data;
this._categories.next(this.categories);
},
error => {
this.loading = false;
console.log('Could not load categories.');
});
}
}
public save(categories: CommandCategory[]) {
this.httpClient.post('/api/CategoryAdmin/SaveCategories', categories).subscribe(() => {
for (var i = 0; i < categories.length; i++) {
if (categories[i].IsDeleted)
categories.splice(i, 1);
}
this.categories = categories;
this._categories.next(this.categories);
}, error => console.log('Could not save categories.'));
}
public add(category: CommandCategory) {
this.httpClient.post('/api/CategoryAdmin/AddCategory', category).subscribe((result: CommandCategory) => {
this.categories.push(result);
this._categories.next(this.categories);
}, error => console.error(error));
}
}
解决方案
您的两种方法都在不同的地方处理 API 的响应:
getCategories()
只需将检索到的类别列表传递给请求它们的组件/服务。addCategory()
实际订阅CategoryService
所以你在两个不同的地方处理数据存储:
您要么持有服务中的类别列表,而组件使用它(因此您的addCategory()
方法可以将新创建的类别推送到现有列表中)
或者您按照中的操作getCategories()
并将新创建的类别返回给添加它的实体(假设它是包含完整类别列表的实体)。
编辑:根据您的评论,我完成了一个快速的Stackblitz并可能解决您的问题。它基本上通过async
管道订阅位于service
.
推荐阅读
- php - 将 google.longrunning.Operations/GetOperation 的绑定映射到任何 Uri 模板
- javascript - 根据对象属性将多个数组组合为一个
- java - Java Spring JPA Hibernate不更新列
- python - 难以遍历字典以在 .txt 中搜索字典中的值
- hibernate-search - 根据索引检查实体的可搜索字段
- python - 在 Azure Batch 上运行 python 脚本
- c++98 - 分配给结构内的引用
- python - 无法在 spyder 中导入张量流
- javascript - 未通过 XMLHttpRequest 发送数据
- javascript - 如何遍历具有嵌套对象的 json 对象以获取所需的数据