【发布时间】:2019-05-09 18:29:50
【问题描述】:
在我的组件中,如果我向下滚动列表,我会调用这个函数来获取更多数据:
onScroll(event) {
if (this.shouldGetData(event.srcElement)) {
this.store.dispatch(new StartAppendRoutesList());
}
}
/* support methods */
shouldGetData(targetEventElement) {
return this.scrollAskForData(targetEventElement) && !this.alllistAlreadyFetched;
}
scrollAskForData(targetEventElement): boolean {
const scrollPercentage = ((targetEventElement.clientHeight + targetEventElement.scrollTop) / targetEventElement.scrollHeight) * 100;
return scrollPercentage > constants.SCROLL_PERCENTAGE_THRESOLD_TO_GET_DATA;
}
在我的副作用中,我有以下几点:
@Effect()
appendRoutes = this.actions$.pipe(
ofType(RoutesListActionTypes.StartAppendRoutesList),
switchMap((action: StartAppendRoutesList) => this.service.getRoutes(fromRoot.initialStateRouteList.currentOffset)
.pipe(
switchMap(result => of(new EndAppendRoutesList(result))),
catchError(err => of(new OnError(err.message)))
))
);
我的行为如下:
StartAppendRoutesList = '[routes] Starting Adding More items to route list',
EndAppendRoutesList = '[routes] Ending Adding More items to route list',
并具有以下代码:
export class EndAppendRoutesList implements Action {
readonly type = RoutesListActionTypes.EndAppendRoutesList;
payLoad: RouteList;
constructor(payLoad: RouteList) {
this.payLoad = payLoad;
}
}
export class StartAppendRoutesList implements Action {
readonly type = RoutesListActionTypes.StartAppendRoutesList;
}
我的减速器是这样的:
case RoutesListActionTypes.StartAppendRoutesList:
return {
...state,
processingRoute: true,
};
case RoutesListActionTypes.EndAppendRoutesList:
const queryResult = action;
return {
...state,
processingRoute: false,
currentOffset: state.currentOffset + 5,
routesList: {
results: state.routesList.results.concat(queryResult.payLoad.results)
}
};
现在乍一看,当我应用偏移量以检索一定数量的数据,或者如果我选择检索服务中的整个列表时,一切正常:
getRoutes(offset: number): Observable<any> {
const numberToRetrieve = 5;
const routes = configUrl.routeBaseUrl["routes"]["results"];
return of(routes.slice(offset, numberToRetrieve));
}
显示的错误出现在我的 reducer 中的 concat 方法中:
routesList: {
results: state.routesList.results.concat(queryResult.payLoad.results)
}
我尝试通过创建一个方法来寻找解决方案,该方法将在我的 createStateSubscriptions 方法中返回一个 fetched indicator,该方法在 ngOnInit 中被调用,如下所示:
alllistAlreadyFetched = false;
ngOnInit() {
// state subscriptions
this.createStateSubscriptions();
// attaching listeners
this.createEventScrollSubscription();
// getting initial data
this.store.dispatch(new StartLoadRoutesList());
}
/* subscriptions and observables creation methods*/
createStateSubscriptions() {
// state observable use directly in view through async pipe
this.listObservable$ = this.store
.select((state: RoutesListState) => state);
// all routes fetched indicator
this.listStateSubscription$ = this.store
.select(allListItemsAlreadyFetchedValidators)
.subscribe((allRoutesFetched: boolean) => {
this.alllistAlreadyFetched = allRoutesFetched;
});
}
而我的allListItemsAlreadyFetchedValidators selector 是这样的:
export const allListItemsAlreadyFetchedValidators = createSelector(
selectRoutesList,
state => state.routes.currentOffset,
(currentOffset, TotalRoutes) => currentOffset.currentOffset >= TotalRoutes
);
然后我在.select(allListItemsAlreadyFetchedValidators) 的组件中遇到另一个错误,如下所示:
ERROR in side-list/side-list.component.ts(43,15): error TS2345: Argument of type 'MemoizedSelector<State, boolean>' is not assignable to parameter of type '"routesList" | "processingRoute" | "processingDetail" | "currentOffset" | "selectedRouteItemId" | "selectedRouteItemData" | "errorMessage"'.
Type 'MemoizedSelector<State, boolean>' is not assignable to type '"errorMessage"'.
这是我的 HTML:
<div class="routes-container">
<div class="wrapper-scroll-y grid-scrollbar">
<header class="header" role="banner">
<h1 class="logo">
<a><span>Routes :</span></a>
<mat-icon class="icon">add</mat-icon>
</h1>
<div class="nav-wrap">
<nav class="main-nav" role="navigation">
<ul class="unstyled list-hover-slide" *ngFor="let route of (listObservable$|async).routes.routesList">
<li (click)= "onListItemSelected($event, route.id)"><a>{{route.name}}</a></li>
</ul>
</nav>
</div>
</header>
</div>
<app-loader-indicator [show]="(listObservable$|async).processingRoute"></app-loader-indicator>
</div>
【问题讨论】: