Angular - 如何发出具有多个订阅者/主题的 HTTP 请求

问题描述 投票:0回答:2

我有一个 Angular 服务,它调用 API 并获取页面列表。这些页面是从多个组件订阅的。考虑到这一点,我使用BehaviorSubjects 来确保每个订阅者都能获得更新。

当我想添加一个新页面时,我需要向服务器提交一个HTTP POST请求,并处理响应。在处理它时,我需要更新一个数组,然后调用 next() 将更新发送给所有订阅者。这要求我在 HTTP 调用上有一个订阅者(至少,我认为是这样),以便我可以调用 next()。但是,在调用 next 时,我还希望组件能够更新并让用户知道请求已完成。

这是一个 stackblitz 示例。在 app.component.ts 中,第 38 行调用服务来创建页面。下面是一段注释掉的代码,它将订阅并将 isSaving 变量设置为 false。但是,我无法订阅该方法,因为它已经在pages.service.ts 文件中进行了订阅。

https://stackblitz.com/edit/angular-abi4mn

我希望这个例子比我的胡言乱语更有意义,如果解释不好,我深表歉意。

angular rxjs xmlhttprequest observable behaviorsubject
2个回答
3
投票

当前您在 PagesService 中订阅了可观察对象,调用该方法的组件应该改为订阅它。因此,在您的

PagesService.add
中,您应该返回可观察量,并且可以在调用组件中订阅可观察量:
this.pagesService.add(newPage).subscribe(...)

现在,由于您还想在 POST 请求成功后在 PagesService 中执行操作,因此您可以使用 tap 运算符对可观察结果进行

spy
操作,而不会影响它,如下所示:

页面服务:

public add(page): Observable<any> {
 return this.httpClient
  .post('https://my-json-server.typicode.com/typicode/demo/posts', page)
  .pipe(
     tap(() => {
        this.pages.push(page);
        this._pages.next(this.pages);
     }),
  );
}

0
投票

如果要更新同一页面上的页面数组,请使用 _pages observable 而不是局部变量 page。您只需要做三处更改。

<p>
  In the real life example there will be multiple subscribers to the pages array on the pages service.  When I add to the array, i need to contact the backend server as well as, update the array so the subscribers can pick up the change.  
  </p>
  <p>
  As well as updating the array, it would be nice for the component thats submitting the call to know when the save has completed.  This way i can display some visual information to the user.  In this example i use the isSaving variable.  This is the part i dont know how to handle, i want to add to the pages array, but also have the component subscribe to the http call so that it can do some stuff once the call is complete.
  </p>
  <p>

  Number of Pages: <strong>{{(pagesService._pages | async).length}}</strong> <br />  <br />
  <button (click)="addPage()" [disabled]="isSaving">Add Page</button>
</p>

将 _pages 变量的 private 设置为 public 到服务中。

public _pages = new BehaviorSubject<any[]>([]);

第三个更改需要更新 isSaving 变量。

public getPages() {
    this.pagesService.get().subscribe((result: any[]) => {

      this.pages = result;
this.isSaving = false;
    }, error => {

      console.error(error);
    });
  }

我已经测试了所有场景并且工作正常。 如果您有任何疑问,请告诉我。 谢谢。

© www.soinside.com 2019 - 2024. All rights reserved.