在 Angular 5 中使用 SwitchMap 订阅
Posted
技术标签:
【中文标题】在 Angular 5 中使用 SwitchMap 订阅【英文标题】:Subscribing with SwitchMap in Angular 5 【发布时间】:2019-03-25 05:34:57 【问题描述】:我正在尝试显示包含所有产品的页面和包含类别的部分,但只有类别正在呈现。
我没有在页面上看到产品。
控制台显示错误:
main.653279d3d097093b55e7.js:1 ERROR Error: InvalidPipeArgument: '[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]' for pipe 't'
我的代码:
import Component, OnInit from '@angular/core';
import ProductService from '../product.service';
import Observable, Subscription from 'rxjs';
import AngularFireList from 'angularfire2/database';
import map, switchMap, filter from 'rxjs/operators';
import CategoryService from '../category.service';
import ActivatedRoute from '@angular/router';
import Product from '../models/product';
@Component(
selector: 'app-products',
templateUrl: './products.component.html',
styleUrls: ['./products.component.css']
)
export class ProductsComponent implements OnInit
products: any = ;
productsRef: AngularFireList<any>;
filteredProducts;
categories: Observable<any>;
categoriesRef: AngularFireList<any>;
category;
constructor(route: ActivatedRoute, private productService: ProductService, private categoryService: CategoryService)
this.productsRef = productService.getAll();
this.products = this.productsRef.snapshotChanges().pipe(
map(changes =>
changes.map(c => (key: c.payload.key, ...c.payload.val() ))
)).switchMap (products =>
this.products = products;
return route.queryParamMap;
).subscribe (params =>
this.category = params.get('category');
this.filteredProducts = (this.category) ?
this.products.filter(p => p.category === this.category) : this.products;
);
this.categoriesRef = this.categoryService.getAll();
this.categories = this.categoriesRef.snapshotChanges().pipe(
map(changes =>
changes.map(c => (key: c.payload.key, ...c.payload.val() ))
)
);
有解决此问题的建议吗?
【问题讨论】:
向我们展示您用于显示数据的pipe
的代码
getAll() return this.db.list('/products');
【参考方案1】:
你应该使用pipe()
this.products = this.productsRef.snapshotChanges().pipe(
map(changes =>
changes.map(c => (key: c.payload.key, ...c.payload.val() ))
),
switchMap (products =>
this.products = products;
return route.queryParamMap;
)
).subscribe (params =>
this.category = params.get('category');
this.filteredProducts = (this.category) ?
this.products.filter(p => p.category === this.category) : this.products;
);
【讨论】:
您的回答很好,但我们可以看到作者已经使用pipe(...)
,但并非在所有情况下都使用。由于switchMap
超出pipe
方法范围并且它以旧方式使用(按点链接函数运算符)我要补充一点,所有这些都应该在pipe(...)
内。
Buczkowski,我该怎么做?【参考方案2】:
switchMap
签名期望这个函数应该返回Observable<any>
:
public switchMap(project: function(value: T, ?index: number): ObservableInput, resultSelector: function(outerValue: T, innerValue: I, outerIndex: number, innerIndex: number): any): Observable
当您返回 route.queryParamMap
时,它不是 ObservableInput
类型。尝试替换这一行:
return route.queryParamMap;
用这个:
return Observable.from(route.queryParamMap);
编辑
由于我的错误,我的第一个答案无效,我尝试将您的 strem 重写为不使用 pipe
并在其开头使用 switchMap
的字符串,以防止重新查询不完整流。
this.products = this.productsRef.snapshotChanges()
.switchMap((products: AngularFireAction<DatabaseSnapshot>[]) =>
return Observable.of(products); // Just re-emit things to guard re-query interruption
)
.map((snap: AngularFireAction<DatabaseSnapshot>[]) => /* Do data manipulation */
let mappedProducts = snap.map((s: AngularFireAction<DatabaseSnapshot>) =>
return key: s.payload.key, ...c.payload.val()
)
return mappedProducts;
)
.do((mappedProducts: any) => /* Side effects */
this.products = mappedProducts;
)
.concatMap(mappedProducts =>
return route.queryParamMap;
)
.subscribe (params =>
this.category = params.get('category');
this.filteredProducts = (this.category) ?
this.products.filter(p => p.category === this.category) : this.products;
);
【讨论】:
错误“类型 上不存在属性'get'。与 .this.category = params.get('category') 一致。单词“get”带下划线 @Vini Pineda 非常抱歉,根据角度文档 queryParamMap alredy 是以下类型的可观察对象:Observable<ParamMap>
。当您应用 mi“修复”时,您的代码将与嵌套的 observables (Observable<Observable<ParamMap>>
) 一起使用,这是您完全不会使用的。很抱歉我的错误,我没有检查文档。以上是关于在 Angular 5 中使用 SwitchMap 订阅的主要内容,如果未能解决你的问题,请参考以下文章
Angular 2:为啥在检索路由参数时使用 switchMap?
为啥 switchMap 在 Angular 拦截器(Angular 9)中不起作用
在Angular App中的Obseable POST请求中使用switchMap
使用 switchmap 和 forkjoin 链接 observables 不能按预期工作 angular typescript rxjs