所以我正在研究的项目使用了角度数据表组件。我对组件进行了一些自定义(最大页面大小等),并通过HttpClient组件从.NET Core WebAPI加载数据。大多数数据是静态的 由于我不想每次都向API查询一些静态数据,因此我想缓存来自API的响应,并在缓存未超时的情况下重用它们。
我尝试了各种缓存机制,但是所有机制都有相同的问题。我什至开始了一个新项目,仅涉及基本要点,但同样的问题重复出现
显示网格的组件:
<table datatable id="productGrid" [dtOptions]="dtOptions" [dtTrigger]="dtTrigger"
class="table table-striped table-hover">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let product of products">
<td>{{ product.productId }}</td>
<td>{{ product.nameCleaned }}</td>
</tr>
</tbody>
</table>
export class ProductComponent implements OnDestroy {
dtOptions: DataTables.Settings;
dtTrigger: Subject<any> = new Subject();
products: Product[] = [];
constructor(private http: HttpClient) {
this.dtOptions = {
pagingType: 'full_numbers',
pageLength: 10,
responsive: true,
dom: '<"dataTables_wrapper dt-bootstrap4"<"row"<"col-sm-12 col-md-6"<"dataTables_length"l>><"col-sm-12 col-md-6"<"dataTables_filter"f>>>rtp>'
};
//this.dtOptions.columnDefs.push({ "visible": false, "searchable": false, "targets": 0 });
this.http.get<Product[]>('https://localhost:44331/api/product/products').subscribe((products) => {
this.products = products;
this.dtTrigger.next();
});
}
ngOnDestroy(): void {
this.dtTrigger.unsubscribe();
}
}
拦截器
@Injectable()
export class CachingInterceptor implements HttpInterceptor {
constructor(private cache: CacheMapService) {}
intercept(req: HttpRequest<any>, next: HttpHandler) {
if (!this.isRequestCachable(req)) {
return next.handle(req);
}
const cachedResponse = this.cache.get(req);
if (cachedResponse !== null) {
return of(cachedResponse);
}
return next.handle(req).pipe(
tap(event => {
if (event instanceof HttpResponse) {
this.cache.put(req, event);
}
})
);
}
private isRequestCachable(req: HttpRequest<any>) {
return (req.method === 'GET') && (req.url.indexOf(CACHABLE_URL) > -1);
}
}
export const MAX_CACHE_AGE = 20000; // in milliseconds
@Injectable()
export class CacheMapService implements Cache {
cacheMap = new Map<string, CacheEntry>();
get(req: HttpRequest<any>): HttpResponse<any> | null {
const entry = this.cacheMap.get(req.urlWithParams);
if (!entry) {
return null;
}
const isExpired = (Date.now() - entry.entryTime) > MAX_CACHE_AGE;
return isExpired ? null : entry.response;
}
put(req: HttpRequest<any>, res: HttpResponse<any>): void {
const entry: CacheEntry = { url: req.urlWithParams, response: res, entryTime: Date.now() };
this.cacheMap.set(req.urlWithParams, entry);
this.deleteExpiredCache();
}
private deleteExpiredCache() {
this.cacheMap.forEach(entry => {
if ((Date.now() - entry.entryTime) > MAX_CACHE_AGE) {
this.cacheMap.delete(entry.url);
}
})
}
}
export interface CacheEntry {
url: string;
response: HttpResponse<any>
entryTime: number;
}
export abstract class Cache {
abstract get(req: HttpRequest<any>): HttpResponse<any> | null;
}
app.module.ts
export const httpInterceptorProviders = [
{ provide: HTTP_INTERCEPTORS, useClass: CachingInterceptor, multi: true }
];
const routes: Routes = [
{ path: 'products', component: ProductComponent },
{ path: '', component: AppComponent },
];
@NgModule({
declarations: [
AppComponent,
ProductComponent
],
imports: [
BrowserModule,
DataTablesModule,
HttpClientModule,
RouterModule.forRoot(routes)
],
providers: [httpInterceptorProviders,
CacheMapService,
{ provide: Cache, useClass: CacheMapService }],
bootstrap: [AppComponent]
})
export class AppModule { }
我的问题是,当数据来自缓存时,不会执行数据表布局。如果从API提取数据,一切正常,并且网格的样式正确,但是当结果来自缓存时,布局是正确的,将显示所有行(无分页),不显示搜索框,依此类推。表格没有任何格式。