Angular 使用RxJS,如何通过另一个动作流触发观察
所以我试图通过angular和RxJS构建一个列表组件。 该列表有许多功能,如:Angular 使用RxJS,如何通过另一个动作流触发观察,angular,rxjs,reactive-programming,angular-reactive-forms,Angular,Rxjs,Reactive Programming,Angular Reactive Forms,所以我试图通过angular和RxJS构建一个列表组件。 该列表有许多功能,如: 逐字搜索 更改页码 更改页面大小 按字段筛选 分类 搜索服务代码: private seachItemSubject = new BehaviorSubject<string>(""); private pageLimitSubject = new BehaviorSubject<number>(10); private pageNumberSubject = new
- 逐字搜索
- 更改页码
- 更改页面大小
- 按字段筛选
- 分类
private seachItemSubject = new BehaviorSubject<string>("");
private pageLimitSubject = new BehaviorSubject<number>(10);
private pageNumberSubject = new BehaviorSubject<number>(0);
private orderingSubject = new BehaviorSubject<ListOrder>({});
private filteringSubject = new BehaviorSubject<any>({});
searchItemAction$ = this.seachItemSubject.asObservable();
pageLimitAction$ = this.pageLimitSubject.asObservable();
pageNumberAction$ = this.pageNumberSubject.asObservable();
orderingAction$ = this.orderingSubject.asObservable();
filteringAction$ = this.filteringSubject.asObservable();
combination$ = Observable.combineLatest(
this.searchItemAction$,
this.pageLimitAction$,
this.pageNumberAction$,
this.orderingAction$,
this.filteringAction$
)
changeSeachItem(searchItem: string) {
this.seachItemSubject.next(searchItem);
}
changePageLimit(pageLimit: number) {
this.pageLimitSubject.next(pageLimit);
}
changePageNumber(pageNumber: number) {
this.pageNumberSubject.next(pageNumber);
}
changeOrdering(listOreder: ListOrder) {
this.orderingSubject.next(listOreder);
}
changeFilters(filters: any) {
this.filteringSubject.next(filters)
}
我不确定这是否是正确的答案,所以如果你有更好的答案,请告诉我
谢谢正如您所发现的,您不能使用下面的原始解决方案,因为当从
applyFilters
调用changePageNumber
和changeFilters
时,CombineTest
将同时启动
另一种方法是使用通过scan
操作符实现的单个状态对象,并一次更新其中的一个或多个属性。这意味着每次“操作”只调用从它触发的服务一次
顺便说一句,您当前正在每个行为子对象中存储您的“状态”,并将其组合
class ListState {
searchItem: any = "";
pageLimit: any = 10;
pageNumber: any = 0;
ordering: any = "asc";
filtering: any = "";
}
const listStateUpdatesSubject = new BehaviorSubject<Partial<ListState>>(null);
const listStateUpdates$ = listStateUpdatesSubject.asObservable();
// fires once per state update, which can consist of multiple properties
const currListState$ = listStateUpdates$.pipe(
filter(update => !!update),
scan<Partial<ListState>, ListState>(
(acc, value) => ({ ...acc, ...value }), new ListState)
);
const callListService$ = currListState$.pipe(map(state => listService(state)));
function changeOrdering(listOreder: string) {
changeState({ ordering: listOreder });
}
function changeFilters(filters: any) {
changeState({ pageNumber: 0, filtering: filters }); // set both page number and filtering
}
// etc
将页面更改事件流组合为您拥有的主题和从过滤器更改事件派生的可观察事件的合并。pageChange::=manualPageChange+FilterChange我不太明白,你介意写代码吗?filterApplied$现在是一个observable@MFarahat参见上面的编辑版本,根据传递到
applyFilters
的过滤器
参数的类型,它现在是可观察的,但它向服务器2发送一个已取消的请求和一个已通过的请求。有没有办法一个电话就搞定?Thanks哪些服务方法导致服务器被调用?该服务器正在被另一个服务调用,该服务是从此行中的组件调用的结果$:Observable=this.listSearchService.combination$.switchMap(([filterItem,pageLimit,pageNumber,ordering,filters])=>this.listService.query({
applyFilters(filters: any) {
this.listSearchService.changePageNumber(0);
this.listSearchService.changeFilters(filters);
this.listSearchService.commit.next() -----> so it would change both then start the combine latest
console.log(filters)
}
class ListState {
searchItem: any = "";
pageLimit: any = 10;
pageNumber: any = 0;
ordering: any = "asc";
filtering: any = "";
}
const listStateUpdatesSubject = new BehaviorSubject<Partial<ListState>>(null);
const listStateUpdates$ = listStateUpdatesSubject.asObservable();
// fires once per state update, which can consist of multiple properties
const currListState$ = listStateUpdates$.pipe(
filter(update => !!update),
scan<Partial<ListState>, ListState>(
(acc, value) => ({ ...acc, ...value }), new ListState)
);
const callListService$ = currListState$.pipe(map(state => listService(state)));
function changeOrdering(listOreder: string) {
changeState({ ordering: listOreder });
}
function changeFilters(filters: any) {
changeState({ pageNumber: 0, filtering: filters }); // set both page number and filtering
}
// etc
...
orderingAction$ = this.orderingSubject.asObservable();
filteringAction$ = this.filteringSubject.asObservable();
filterApplied$ = filteringAction$.pipe(map(filter => applyFilters(filter)));
applyFilters(filters: any) {
this.listSearchService.changePageNumber(0);
this.listSearchService.changeFilters(filters);
return filters;
}
combination$ = Observable.combineLatest(
this.searchItemAction$,
this.pageLimitAction$,
this.pageNumberAction$,
this.orderingAction$,
this.filterApplied$ // instead of filteringAction$
)