【发布时间】:2019-06-12 22:52:07
【问题描述】:
在我的 Angular 应用程序中,我有一个函数接收一些用户选择的过滤器,然后根据这些过滤器值返回过滤后的数据。如果没有应用过滤器,则返回未过滤的数据。
过滤器值通过 Angular 的 EventEmitter() 从一个组件传递到另一个组件,所以在接收组件模板中,我有这个:
<div class="page-content">
<grid [records]="records"
(sendFilterValues)="onFilterReceived($event)">
</grid>
</div>
我遇到的问题(我已经解决了好几天了)是因为过滤器是通过另一个组件的 EventEmitter() 进入的,这会导致接收这些选择的函数,然后使网络调用多次触发。
函数中间的console.log语句特别告诉我进入这个函数的过滤器导致它触发10次。
因此,对于用户来说,最终发生的事情是,他们在视图中看到数据发生了多次移动,因为多个调用发出 - 一些用于未过滤的数据,一些用于过滤的数据。我想控制它,所以只发出一个网络请求。
所以我想要做的是,因为这是一个可观察的,是使用某种 RxJS 运算符来进行一次调用。但是,我似乎无法让它工作。据我所知,我申请的运营商没有任何效果。
这是我的代码:
import { last } from 'rxjs/operators';
public onFilterReceived(values)
{
let filters = {};
if (values) {
filters = values;
}
this.route.params.subscribe(
(params: any) => {
this.page = params['page'];
}
);
let fn = resRecordsData => {
this.records = resRecordsData;
};
console.count('onFilterReceived() is firing'); // fires 10 times
this.streamFiltersService.getByFilters(
this.page - 1, this.pagesize, this.currentStage, this.language = filters['language'], this.location = filters['location'],
this.zipcode = filters['zip'], this.firstName = filters['firstName'], this.lastName = filters['lastName'],
this.branch = filters['branch'], fn).last;
}
虽然我的组件中有导入,但我的 IDE 提示它从未真正读取过。但是,当我在下面的代码之后立即添加. 时,如下所示:
this.streamFiltersService.getByFilters(
this.page - 1, this.pagesize, this.currentStage, this.language = filters['language'], this.location = filters['location'],
this.zipcode = filters['zip'], this.firstName = filters['firstName'], this.lastName = filters['lastName'],
this.branch = filters['branch'], fn).
...各种 RxJS 运算符显示为选项,包括 last 运算符。
顺便说一句,这 10 次触发会返回到原始过滤器组件,我从下面的 console.log 向我显示这会触发 10 次 - 并且这会传递给接收组件。如果有另一种方法可以控制它只发射一次,那也可能解决我的问题。这是代码:
async onFilterValuesReceived({ 'zip' : zipArray, 'firstName' : firstName,
'lastName' : lastName, 'language' : language, 'location' : location, 'branch' : branch })
{
let filtersObj = { 'zip' : zipArray, 'firstName' : firstName,
'lastName' : lastName, 'language' : language, 'location' : location, 'branch' : branch };
this.sendFilterValues.emit(await filtersObj);
console.count('sending these...'); // fires 10 times
}
那么,如果是这样的话,为什么这个操作符在这里不起作用呢?我是在使用错误的运算符,还是以错误的方式使用它?还是有其他问题?我得到与使用这些运算符有关的零错误,但我也没有看到它们对函数的执行有任何影响。
顺便说一下,服务层中网络调用的代码是这样的:
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 });
}
...它又从根服务层调用它:
public get(args: {
req: string,
reqArgs?: any,
reqBody?: any,
callback?: IRequestCallback
}): Observable<Response>
{
args['reqType'] = 'get';
return this.runHttpRequest(args);
}
API 服务级别的结构是否存在问题?我们在所有这种类型的 GET 请求中使用它。当我在这里尝试使用 takeLast 运算符时,我收到一个 TS 错误:
[ts] 类型 '(this: Observable, count: number) => Observable' 不可分配给类型“可观察”。财产 '_isScalar' 在类型 '(this: Observable, count: number) => Observable'。
我已经为这个问题绞尽脑汁好几天了,如果我能解决这个问题,我将不胜感激。
我现在也完全接受非 RxJS 选项,如果有其他方法可以解决这个问题。
【问题讨论】: