如何在将新数据发布到后端后更新对 GET 请求的订阅
How to update a subscription to a GET-request after posting new data to the backend
我实现了一项服务,该服务利用 Angular 的 HttpClient 向我的后端发出 GET 请求。它 returns 员工列表:
getAllEmployees(): Observable<Employee[]> {
return this.httpClient.get<Employee[]>(this.EMPLOYEES_URL);
}
我在 table 组件的 ngOnInit()
方法中订阅了这个服务,用返回的数据填充一个数组。我的 table 的行是根据数组中的内容动态构建的。
现在,我正在向我的后端发布一名新员工。然而,table 没有更新。
我对 Angular observables 的理解是它们监视后端(在本例中),每当有变化时,订阅内的代码就会执行。显然这种理解是错误的,我想知道:如何在我的 table-component 中强制更新订阅?
我认为您可能缺少的信息是,从 HttpClient 方法中 return 的 Observables 在第一个 return.
完成后完成
当您使用 2 个独立的组件时,您将需要一些方法来通知必须获取新数据,或者需要一些方法来保持 observable 处于打开状态 - 我们可以通过服务来做到这一点。我认为以下内容应该适合您。
在服务中我们可以定义:
private employeesUpdated$ = new Subject<void>();
employees$ = employeesUpdated$.pipe(
startsWith({}),
switchMap(() =>
this.httpClient.get<Employee[]>(this.EMPLOYEES_URL)
)
);
然后您可以在 POST 上添加:
this.httpClient.post<something>(... stuff ...).pipe(
tap(() => {
this.employeesUpdated.next();
})
)
这将允许您在您的组件中订阅 employees$,并且每次您 post 一个新的订阅时,它将执行一个新的获取请求,因为 observable 将保持打开状态。不过请妥善处理此订阅!
您可以在此处的官方文档中找到更多关于 rxjs 和 Observables 的信息:
https://rxjs.dev/guide/overview
这也是一个很好的资源:
https://www.learnrxjs.io/
如果你只想追加到最初得到的数组,而不是在每次创建后从服务器获取所有内容,我认为这样的事情会起作用:
服务中:
private employeeAdded$ = new Subject<Employee>();
private serverEmployees$ = this.httpClient.get<Employee[]>(this.EMPLOYEES_URL);
employees$ = merge(
serverEmployees$,
employeeAdded$.pipe(
map(x => ([x]))
)
).pipe(
scan((acc, cur) => acc.concat(cur), [])
);
基本上合并将采用多个可观察值,并输出一个。这将进入扫描,它将使用提供的函数进行累积,并在每次累积后发出。这些文件是
https://rxjs.dev/api/index/function/merge 和
https://rxjs.dev/api/index/function/scan.
对于您的创建(请记住,在 post 上从服务器返回对象,因此它具有实体的 ID):
this.httpClient.post<something>(... stuff ...).pipe(
tap((employee: Employee) => {
this.employeesUpdated.next(employee);
})
)
我实现了一项服务,该服务利用 Angular 的 HttpClient 向我的后端发出 GET 请求。它 returns 员工列表:
getAllEmployees(): Observable<Employee[]> {
return this.httpClient.get<Employee[]>(this.EMPLOYEES_URL);
}
我在 table 组件的 ngOnInit()
方法中订阅了这个服务,用返回的数据填充一个数组。我的 table 的行是根据数组中的内容动态构建的。
现在,我正在向我的后端发布一名新员工。然而,table 没有更新。
我对 Angular observables 的理解是它们监视后端(在本例中),每当有变化时,订阅内的代码就会执行。显然这种理解是错误的,我想知道:如何在我的 table-component 中强制更新订阅?
我认为您可能缺少的信息是,从 HttpClient 方法中 return 的 Observables 在第一个 return.
完成后完成当您使用 2 个独立的组件时,您将需要一些方法来通知必须获取新数据,或者需要一些方法来保持 observable 处于打开状态 - 我们可以通过服务来做到这一点。我认为以下内容应该适合您。
在服务中我们可以定义:
private employeesUpdated$ = new Subject<void>();
employees$ = employeesUpdated$.pipe(
startsWith({}),
switchMap(() =>
this.httpClient.get<Employee[]>(this.EMPLOYEES_URL)
)
);
然后您可以在 POST 上添加:
this.httpClient.post<something>(... stuff ...).pipe(
tap(() => {
this.employeesUpdated.next();
})
)
这将允许您在您的组件中订阅 employees$,并且每次您 post 一个新的订阅时,它将执行一个新的获取请求,因为 observable 将保持打开状态。不过请妥善处理此订阅!
您可以在此处的官方文档中找到更多关于 rxjs 和 Observables 的信息: https://rxjs.dev/guide/overview 这也是一个很好的资源: https://www.learnrxjs.io/
如果你只想追加到最初得到的数组,而不是在每次创建后从服务器获取所有内容,我认为这样的事情会起作用:
服务中:
private employeeAdded$ = new Subject<Employee>();
private serverEmployees$ = this.httpClient.get<Employee[]>(this.EMPLOYEES_URL);
employees$ = merge(
serverEmployees$,
employeeAdded$.pipe(
map(x => ([x]))
)
).pipe(
scan((acc, cur) => acc.concat(cur), [])
);
基本上合并将采用多个可观察值,并输出一个。这将进入扫描,它将使用提供的函数进行累积,并在每次累积后发出。这些文件是 https://rxjs.dev/api/index/function/merge 和 https://rxjs.dev/api/index/function/scan.
对于您的创建(请记住,在 post 上从服务器返回对象,因此它具有实体的 ID):
this.httpClient.post<something>(... stuff ...).pipe(
tap((employee: Employee) => {
this.employeesUpdated.next(employee);
})
)