angular - 在 Angular 中使用带有 RxJS 的声明式/响应式(Reactive)数据访问方法时如何获取 "pass"数据?

标签 angular typescript rxjs

Angular 中数据访问的经典模式建议如下代码:
经典数据访问模式

getProducts(): Observable<Product[]> {
  return this.http.get<Product[]>(this.productsUrl)
    .pipe(
      tap(data => console.log(JSON.stringify(data))),
      catchError(this.handleError)
    );
上面我们有一个方法返回一个 Observable。当数据从 http 端点返回时,该 Observable 以 Product[] 定义的形状发出数据。泛型参数 where Product是一个接口(interface)。
对于更具 react 性的应用程序,通常建议使用声明性/ react 性方法。它将上述方法更改为如下属性声明:
响应式(Reactive)数据访问模式
products$ = this.http.get<Product[]>(this.url)
  .pipe(
    tap(data => console.log(JSON.stringify(data))),
    catchError(this.handleError)
  );
请注意,这在服务中为 Observable 声明了一个属性,而不是一个方法。 $后缀 products$是一种用于区分 Observable 属性与其他类型数据结构(例如通用对象或数组)的约定。
当存在 UI 交互性(例如基于选择的过滤)、处理复杂数据(例如组合来自多个端点的数据)以及跨组件共享数据(例如每个组件需要使用react时)时,通常会使用此模式当数据发生变化时)。
响应式(Reactive)数据访问模式存在一个常见问题。使用这种技术时,我们如何“传递”URL 所需的数据?
例如,假设 http 请求需要一个类别来只下拉该类别的产品:
this.http.get<Product[]>(`${this.url}?cat=${catId}`)
没有方法怎么能把这个类“传入”?

最佳答案

与其考虑如何“传递”数据,不如考虑如何随着时间的推移“发出”该值。为了发出数据,我们使用 Subject 定义我们自己的 Observable或 BehaviorSubject .

private categorySubject = new Subject<number>();
categorySelectedAction$ = this.categorySubject.asObservable();

products$ = this.categorySelectedAction$.pipe(
 switchMap(catId=>this.http.get<Product[]>(`${this.url}?cat=${catId}`))
    .pipe(
      tap(data => console.log(data)),
      catchError(this.handleError)
  ));

selectedCategoryChanged(categoryId: number): void {
  this.categorySubject.next(categoryId);
}
在上面的代码中,我们使用 Subject 定义了我们的 Observable .我们将 Subject 声明为私有(private),因此无法从我们的服务外部访问它。然后我们使用 asObservable() 公开该主题的只读部分.
每当用户选择不同的类别时,组件就会调用 selectedCategoryChanged它将选定的 categoryId 发送到我们的主题定义的流中。
对于 products$ , 当一个值被发出时,它会通过一组运算符进行管道传输。 switchMap是一个高阶映射运算符,它自动订阅内部 Observable(this.http.get...)并展平结果。然后将指定类别的返回产品发送到 products$溪流。
要查看更完整的解决方案,请参阅此 github:https://github.com/DeborahK/Angular-RxJS/tree/master/APM-Final

关于angular - 在 Angular 中使用带有 RxJS 的声明式/响应式(Reactive)数据访问方法时如何获取 "pass"数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68506161/

相关文章:

node.js - 为什么TypeORM需要提供OneToMany的反面,而不需要提供ManyToOne的反面?

javascript - typescript 类型和 .bind

javascript - RxJs - (为什么)Observable 是否在新订阅上发出最新值?

javascript - RxJS:使用常规采样去抖动

angular - 如何在 Angular 应用程序中使用 powerbi-client 依赖项,而不破坏 Jest 测试?

javascript - 如何将按钮放在 Angular mat-table 中?

angular - 一个未处理的异常发生 : Configuration 'es5' is not set in the workspace. ng serve in angular 8 for es5

javascript - 如何在 Angular 7 中对包含特殊字符的查询参数进行编码?

angular - Observable.zip 不是函数

javascript - 如何喂养 rxjs 观察者