我的Angular2应用程序中有一个功能,用户可以选择各种过滤器来过滤在网格视图中返回的数据。这种获取和过滤数据的工作。但是,我需要找到一种方法-最好使用RxJS和类似switchMap()
的方法在更改过滤器选择时取消请求-以便只有最近的请求才能通过网络。
我一直很难使它起作用。因此,我首先需要确定当前的配置是否实际上是可观察到的RxJS,然后确定在何处插入switchMap()
之类的运算符。
这是我的代码的样子:
private sendRequest = _.debounce((languageFilter, locationFilter, zipFilter, firstNameFilter, lastNameFilter, branchFilter) =>
{
this.filtersService.getByFilters(
this.page - 1, this.pagesize, this.currentStage, this.language = languageFilter, this.location = locationFilter,
this.zipcode = zipFilter, this.firstName = firstNameFilter, this.lastName = lastNameFilter,
this.branch = branchFilter,
(resRecordsData) => {
this.records = resRecordsData;
});
}, 200);
public onFilterReceived(values)
{
let languageFilter = [];
let locationFilter = [];
let zipFilter = [];
let firstNameFilter = [];
let lastNameFilter = [];
let branchFilter = [];
this.route.params.subscribe(
(params: any) => {
this.page = params['page'];
this.pn_zip_e = params['pn_zip.e'];
this.pn_firstName_e = params['pn_firstName.e'];
this.pn_lastName_e = params['pn_lastName.e'];
this.pn_location_e = params['pn_location.e'];
this.pn_branch_e = params['pn_branch.e'];
this.pn_language_e = params['pn_language.e'];
}
);
this.pn_language_e === "1" ? languageFilter = values['language'] : languageFilter = [];
this.pn_location_e === "1" ? locationFilter = values['location'] : locationFilter = [];
this.pn_zip_e === "1" ? zipFilter = values['zip'] : zipFilter = [];
this.pn_firstName_e === "1" ? firstNameFilter = values['firstName'] : firstNameFilter = [];
this.pn_lastName_e === "1" ? lastNameFilter = values['lastName'] : lastNameFilter = [];
this.pn_branch_e === "1" ? branchFilter = values['branch'] : branchFilter = [];
this.sendRequest(languageFilter, locationFilter, zipFilter, firstNameFilter, lastNameFilter, branchFilter);
};
从我的filterService调用的getByFilters()
函数如下所示:
public getByFilters(page, pagesize, stage?, language?, location?, zipcode?, firstName?, lastName?, branch?, fn?: any)
{
return this.apiService.get({
req: this.strReq, reqArgs: { page, pagesize, stage, language, location, zipcode, firstName, lastName, branch }, callback: fn });
}
依次在我们的中央请求控制器服务(apiService)中调用GET请求,如下所示:
public get(args: {
req: string,
reqArgs?: any,
reqBody?: any,
callback?: IRequestCallback
}): Observable<Response>
{
args['reqType'] = 'get';
return this.runHttpRequest(args);
}
一旦收到响应,便将其分配给“ this.records”,然后在我的视图中使用它遍历“ this.records.data”(它是一个数组),以将记录打印到屏幕上。
因此,从我上面的代码中,此行是我获取响应并将其分配给“ this.records”的地方:
this.records = resRecordsData;
所以,我的第一个问题是,如何确定这里是否有可观察到的RxJS,然后如何使用类似switchMap()
的运算符来处理取消先前的过滤器请求?
我尝试了这个,但是没有用。我的猜测是语法不正确:
private sendRequest = _.debounce((languageFilter, locationFilter, zipFilter, firstNameFilter, lastNameFilter, branchFilter) =>
{
this.streamFiltersService.getByFilters(
this.page - 1, this.pagesize, this.currentStage, this.language = languageFilter, this.location = locationFilter,
this.zipcode = zipFilter, this.firstName = firstNameFilter, this.lastName = lastNameFilter,
this.branch = branchFilter,
(resRecordsData) => {
resRecordsData.switchMap((res) => {
this.records = res;
});
console.log('records: ', this.records);
});
}, 200);
首先,为了确保我正在树立正确的树,我想有一种方法来确定我在这里的响应是否实际上是可观察到的RxJS。而且,如果没有,找到一种将其转换为一个的方法,这样我就可以在其上使用switchMap()
。
答案 0 :(得分:0)
我为switchMap
创建了实例,并使用reactForm创建了两个输入。可以使用fromEvent(inputElement,'change')
代替this.inputElement.valueChanges
。
// We want combine of all lastest values.
combineLatest(
// We merge default name with observable of name input.
merge(
of('default'),
// From input we want to be inform after 200ms debounce and if they have change.
this.name.valueChanges.pipe(debounceTime(200), distinctUntilChanged())
),
// We merge default choice with observable of choice input.
merge(
of('value 1'),
this.choice.valueChanges.pipe(debounceTime(200), distinctUntilChanged())
)
).pipe(map(e => {
// We construct the request payload
return {
name: e[0],
choice: e[1]
}
// Ignore combined default value, ask api and subscribe to answer.
})).pipe(skip(1), switchMap(e => this.myApi(e))).subscribe(console.log);
为了确保理解每个步骤,我强烈建议您按组成变量对其进行拆分,并console.log每个订阅的流。示例:
可观察的输入
this.name.valueChanges.pipe(debounceTime(200), distinctUntilChanged()).subscribe(console.log)
在经过200ms的反跳后,将输出您当前的输入值,如果该值与先前发出的值相比有变化。
可观察到的具有默认值的输入
merge(
of('default'),
this.name.valueChanges.pipe(debounceTime(200), distinctUntilChanged())
),
我们将立即默认值与输入流上发出的将来值合并。
最新组合
从先前的合并合并中,我们希望将每个输入的最新发射值合并为单个流。
地图
.pipe(map(e => {
// We construct the request payload
return {
name: e[0],
choice: e[1]
}
// Ignore combined default value, ask api and subscribe to answer.
})
因为CombineLatest将创建作为参数提供的最新发射流的数组。我们希望将此数组映射到api的真实有效负载对象。
switchMap
switchMap(e => this.myApi(e)))
您拥有了有效载荷(通过前面描述的地图生成),将其转换为新的可观测值。现在,您可以简单地进行订阅,并且您将神奇地根据输入值的集合获得API的答案,并自动取消不再相关的先前请求。
要基于路径Params,您可以执行以下操作。
ngOnInit() {
// From url params change, we map output with default value.
const routeParams$ = this.route.params.pipe(map(params => {
return {
user: '',
choice: '',
...params
};
}));
// Uncomment me to see it in action.
// routeParams$.subscribe(console.log);
// Transform this payload to http request and subscribe to it.
routeParams$.pipe(switchMap(e => this.myApi(e))).subscribe(console.log);
}