首页 > 解决方案 > 当我单击角度按钮时如何实现基于推送的架构?

问题描述

我通过 RxJS 和 Angular 了解了基于推送的架构。

从我了解到的情况中,我了解到 Pull-Base 架构是视图调用获取数据的时候。

这可以使用 oberables 或通过赋值:

 users$ = this.facade.users$

 loadUser() { this.facade.loadUser(); }

在门面:

 users$ = new BeahviorSubject();

 loadUser() { this.http.get('...').subscribe(users => { this.users$.next(users); }) }

在 Push-Base 中,它应该对以下更改做出反应:

  search = new FormControl();

  search.valueChanges().pipe(tap(searchTerm => searchSomething(searchTerm)));

当涉及到事件时,这很好。但是如果我需要“反应”来点击按钮呢?

基本上按钮保存“拉”数据。所以我对此感到困惑,如果有人可以解决这个冲突,那将会很有帮助。

标签: angularrxjs

解决方案


虽然组件仍然会在按钮单击时触发“push”事件,但该事件的效果可以反应性地发生。

使用一个非常基本的搜索表单的例子......


服务文件

private searchTerm = new Subject<string>();

public searchResult$ = this.searchTerm.pipe(
  switchMap(searchTerm =>
    this.http.get<string[]>(`url?${searchTerm}`)
  ),
  startWith([])
);

public newSearchTerm = (newTerm:string) => {
  this.searchTerm.next(newTerm);
}

我们声明了一个私有主题,它将发出我们的搜索查询。

接下来,我们声明将接收发出的搜索查询的 observable,并将其插入到我们的 HTTP 请求中。我们可以返回 http 请求,因为它返回一个可观察的响应。

由于searchTerm主题在开始时没有发出任何内容,因此我们将初始值(一个空数组)与 operator 相加startWith()

最后,我们创建一个公共方法,允许其他类发出下一个搜索词。


组件 TS 文件

public searchInput = new FormControl('');

public searchResult$ = this.service.searchResult$;

public searchEvent = () => {
  this.service.newSearchTerm(searchInput.value);
}

我们像您在示例中所做的那样声明我们的 FormControl 搜索输入。

接下来,我们从我们的服务中订阅searchResult$observable。同样,这依赖于该服务主题来发出搜索词。

最后,我们创建一个方法来处理按钮单击事件。当该方法返回 void 时,它会调用 service 方法来发出一个新的搜索词。

这将导致我们组件的状态searchResult$做出反应,显示从服务 HTTP 请求返回的值。


组件 HTML 文件

<input formControlName="searchInput" />
<button (click)="searchEvent()">Search</button>

<ul>
  <li *ngFor="let result of searchResult$ | async">{{ result }}</li>
</ul>

最后,我们设置我们的 HTML。按钮输出将调用该searchEvent()方法。我们使用async管道订阅searchResult$. 在此视图中,这会将整个可观察链放入一个订阅中。当组件被销毁时(屏幕变化),它将导致整个可观察链取消订阅。


推荐阅读