Angular Datatable не применяет настройки после кэшированного запроса - PullRequest
0 голосов
/ 28 мая 2019

Так что в проекте, над которым я работаю, используется компонент angular datatables. Я выполняю некоторые настройки компонента (максимальный размер страницы и т. Д.) И загружаю данные из .NET Core WebAPI через компонент HttpClient. Большая часть данных довольно статична Поскольку я не хочу каждый раз запрашивать у 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, все работает и сетка оформляется правильно, но когда результат получается из кеша, компоновка верна, все строки отображаются (без разбивки на страницы), окно поиска не отображается и т. Д. Это просто таблица без какого-либо форматирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...