在组件内部,我调用此函数是为了在向下滚动列表时获取更多数据:
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)
}
我试图通过创建一种方法来寻找解决方案,该方法将在我的fetched indicator
方法内部返回一个createStateSubscriptions
,该方法在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>
答案 0 :(得分:1)
如果您的state.routesList.results未定义或不是数组,则将面对该错误。要解决它,您必须在concat方法之前检查它。如果不是数组或未定义,则可以直接将结果设置为queryResult.payLoad.results
routesList: {
results: (state.routesList.results && state.routesList.results instanceOf Array)? state.routesList.results.concat(queryResult.payLoad.results) : queryResult.payLoad.results
}