我有以下 rxjs 组件:
search$ = this.searchCriteria$.pipe(
switchMap((search: SearchProgramsCriteria) => this.httpService.getProgramsSearchList(search)),
scan((acc, curr)=>{
/* Record the min and max pages we've already visited START */
// If the current page is lower than the currently marked acquired one, then adjust our min number
if ((curr.pagination.current_page < acc.pagination.minPageNumberAcquired)){
acc.pagination.minPageNumberAcquired = curr.pagination.current_page;
}
// If the current page is higher than the currently marked acquired one, then adjust our max number
if ((curr.pagination.current_page > acc.pagination.maxPageNumberAcquired)){
acc.pagination.maxPageNumberAcquired = curr.pagination.current_page;
}
/* Record the min and max pages we've already visited END */
/* Depending on the desired loading direction, we either put it at the top or the bottom of the existing array START */
if ((this.loadingDirection === "top")){
acc.data.unshift(...curr.data);
}
else
{
acc.data.push(...curr.data);
}
/* Depending on the desired loading direction, we either put it at the top or the bottom of the existing array END */
return acc;
}),
tap((res) => {
this.unsetLoadingDirection();
})
);
它调用以下 httpservice observable:
getProgramsSearchList(searchCritieria: any): Observable<SearchPrograms> {
return this.http
.post<SearchPrograms>(`myapi/programs`, searchCritieria, { responseType: 'json' })
.pipe(
map((clients: any) => ({
pagination: {
total: clients.pagination.total,
current_page: clients.pagination.current_page,
['sort-order']: clients.pagination['sort-order'],
['sort-by']: clients.pagination['sort-by'],
minPageNumberAcquired: clients.pagination.current_page,
maxPageNumberAcquired: clients.pagination.current_page
},
data: clients.data.map((client: any) => ({
id: client.id,
name: client.meta.name
}))
})),
catchError((err) => {
return this.errorHandler(err);
})
);
}
HTML:
<!-- Top loading START -->
<div class="align-center p-button-tertiary top-loading-button" *ngIf="(loadingDirection === null) && (searchData.pagination.minPageNumberAcquired > 1)">
<a [href]="'/search-programs?page='+(searchData.pagination.minPageNumberAcquired-1)" (click)="loadAtTop($event, searchData.pagination.minPageNumberAcquired-1)" class="p-button">
<span class="p-button-label">Load more</span>
</a>
</div>
<div class="skeleton-card" *ngIf="loadingDirection === 'top'">
<div class="skeleton-1zyqvjb96qq"></div>
</div>
<!-- Top loading END -->
<div class="programs-search-results">
<ul>
<app-program-card *ngFor="let item of searchData.data; let i = index" [detail]="item" [count]="i"></app-program-card>
</ul>
</div>
<!-- Bottom loading START -->
<div class="skeleton-card" *ngIf="loadingDirection === 'bottom'">
<div class="skeleton-1zyqvjb96qq"></div>
</div>
<div class="align-center p-button-tertiary" *ngIf="(loadingDirection === null) && (searchData.pagination.total >= searchData.pagination.maxPageNumberAcquired)">
<a [href]="'/search-programs?page='+(searchData.pagination.maxPageNumberAcquired+1)" (click)="loadAtBottom($event, searchData.pagination.maxPageNumberAcquired+1)" class="p-button">
<span class="p-button-label">Load more</span>
</a>
</div>
<!-- Bottom loading END -->
我的组件监听查询参数的更改,并在更改后调用 api。我的组件具有相当复杂的加载,因为您可以根据您按下的加载按钮加载顶部和底部的项目。它还会记住您已经访问的 minPageNumberAcquired
和 maxPageNumberAcquired
的最小和最大页码。这样您就不会从页面 2 => 1 => 2 转到页面 2 => 1 => 3。
我的组件按原样工作。然而,在我的服务中,我确实不应该声明 minPageNumberAcquired
和 maxPageNumberAcquired
,因为它始终是当前页码。我遇到的问题是,scan
仅在我第二次调用 api 时执行操作,但我的模板从一开始就需要这些 minPageNumberAcquired
和 maxPageNumberAcquired
值为了工作。我是否需要以某种方式在 scan
上声明默认值?
类似于:
scan((acc, curr)=>{
return acc;
}, {pagination: acc.pagination.minPageNumberAcquired, acc.pagination.maxPageNumberAcquired}),
最佳答案
是的,scan
的工作方式类似于 Array.reduce
,您传递一个默认值作为第二个参数。
你的解决方案看起来不错。
scan((acc, curr)=>{
return acc;
}, {pagination: acc.pagination.minPageNumberAcquired, acc.pagination.maxPageNumberAcquired}),
关于javascript - rxjs 在第一次调用时扫描默认属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74976701/