我注意到我正在编写许多与设置服务器端分页,过滤和可搜索的物料表有关的重复代码。
重复的代码主要涉及常规物料表所需的类: * datasource.ts * datastore.ts
我的想法是生成这些类以接受实现特定接口的http服务,该服务将定义一个方法来调用API以过滤结果,并返回类似Observable的类型,其中T为实体。
问题是我似乎不知道该如何实现。 我已经尝试了多种方法,但最终遇到了与类型有关的问题。
这是我到目前为止所拥有的:
http服务接口:
export interface ITableFilterService {
getFilteredData<T>(tableFilter: TableFilter): Observable<T>;
}
http服务本身(问题:Observable不能分配给Observable):
export class EventListMockService implements ITableFilterService {
/* tslint:disable:member-access */
getFilteredData<T>(tableFilter: TableFilter): Observable<T> {
return this.getFilteredListOfItems(tableFilter);
}
public getFilteredListOfItems(filter: TableFilter): Observable<EventItem[]> {
return this.getListOfItems();
}
非常有问题的 datastore.service.ts (需要以某种方式使实体EventItem)具有通用性,并且与此类相关的所有信息:
export class EventDataStoreService {
private copiedData: EventItem[];
public dataChange: BehaviorSubject<EventItem[]> = new BehaviorSubject<EventItem[]>([]);
public unitCount = 0;
get data(): EventItem[] {
return this.dataChange.value;
}
constructor(private service: EventListMockService,
tableFilter: TableFilter) {
this.copiedData = this.data.slice();
this.getUnitList(tableFilter);
}
public getUnitList(tableFilter: TableFilter): void {
this.service.getFilteredListOfItems(tableFilter).subscribe((response) => {
this.copiedData = response;
this.unitCount = response.length;
this.dataChange.next(this.copiedData);
});
}
}
还有一个非常麻烦的datasource.service.ts(需要通用服务和实体):
export class EventDataSourceService extends DataSource<{}> {
public paginator: MatPaginator;
public sort: MatSort;
private filterChange = new BehaviorSubject('');
get filter(): string {
return this.filterChange.value;
}
set filter(filter: string) {
this.filterChange.next(filter);
}
constructor(private dataStore: EventDataStoreService) {
super();
}
public connect(): Observable<EventItem[]> {
const displayDataChanges = [
this.dataStore.dataChange,
this.paginator.page,
this.filterChange,
this.sort.sortChange,
];
return merge(...displayDataChanges).pipe(map(() => {
const data = this.getSortedData();
return data.splice(0, this.paginator.pageSize)
.filter((item: EventItem) => {
let searchString = '';
Object.keys(item).forEach((key) => {
searchString += key ? key.toLowerCase() : '';
});
return searchString.toLowerCase().indexOf(this.filter.toLowerCase()) !== -1;
});
}));
}
public disconnect(): void {
this.filterChange.complete();
}
public getSortedData(): EventItem[] {
return this.dataStore.data.slice();
}
}
也许有人过去做过这样的事情,可以分享解决方案吗?那太好了。哦,诀窍是禁止使用any
:(谢谢!