Deb*_*ahK 5 rxjs typescript angular
Angular 中数据访问的经典模式建议如下代码:
经典数据访问模式
getProducts(): Observable<Product[]> {
return this.http.get<Product[]>(this.productsUrl)
.pipe(
tap(data => console.log(JSON.stringify(data))),
catchError(this.handleError)
);
Run Code Online (Sandbox Code Playgroud)
上面我们有一个方法返回一个 Observable。当数据从 http 端点返回时,该 Observable 以Product[]通用参数定义的形状发出数据,其中Product是一个接口。
对于更具反应性的应用程序,通常建议使用声明性/反应性方法。它将上述方法更改为如下属性声明:
反应式数据访问模式
products$ = this.http.get<Product[]>(this.url)
.pipe(
tap(data => console.log(JSON.stringify(data))),
catchError(this.handleError)
);
Run Code Online (Sandbox Code Playgroud)
请注意,这在服务中为 Observable 声明了一个属性,而不是一个方法。的$上后缀products$是用于区分是观测量VS其它类型的数据结构,如一般的物体或阵列性质的约定。
当存在 UI 交互性(例如基于选择的过滤)、处理复杂数据(例如组合来自多个端点的数据)以及跨组件共享数据(例如每个组件需要做出反应时)时,通常会使用此模式当数据发生变化时)。
反应式数据访问模式存在一个常见问题。使用这种技术时,我们如何“传递”URL 所需的数据?
例如,假设 http 请求需要一个类别来只下拉该类别的产品:
this.http.get<Product[]>(`${this.url}?cat=${catId}`)
Run Code Online (Sandbox Code Playgroud)
没有方法怎么能把这个类“传入”?
Deb*_*ahK 10
与其考虑如何“传递”数据,不如考虑如何随着时间的推移“发出”该值。为了发出数据,我们使用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);
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我们使用Subject. 我们将 Subject 声明为私有,因此无法从我们的服务外部访问它。然后我们使用 公开该主题的只读部分asObservable()。
每当用户选择不同的类别时,组件就会调用selectedCategoryChanged它,将选定的 categoryId 发送到我们的主题定义的流中。
对于products$,当发出一个值时,它会通过一组运算符进行管道传输。TheswitchMap是一个高阶映射运算符,它自动订阅内部 Observable (the this.http.get...) 并将结果展平。然后将指定类别的返回产品发送到products$流中。
要查看更完整的解决方案,请参阅此 github:https : //github.com/DeborahK/Angular-RxJS/tree/master/APM-Final
| 归档时间: |
|
| 查看次数: |
558 次 |
| 最近记录: |