PrimeNG Ленивая загрузка данных с асинхронным каналом - PullRequest
0 голосов
/ 15 марта 2019

У меня есть очень большой объем данных (400 000 записей), которые мне нужно показать в таблице данных PrimeNG.Для этого мне нужна таблица отложенной загрузки, поскольку вы не можете загрузить все данные в таблицу за один раз (это приведет к сбою браузера).

Для создания таблицы я использую следующие технологии:


Что я хочу

Я пытаюсь создать ленивую загрузкутаблица, как показано в PrimeNG документах , где данные загружаются с сервера и показаны в таблице.Когда пользователь переходит к следующей вкладке, загружается и отображается следующий объем данных.

Единственное отличие состоит в том, что я получаю все данные с сервера, прежде чем передать их компоненту таблицы.Таким образом, мне нужно будет только выбрать определенные данные из источника данных и показать их пользователю.


Проблема

При попытке реализовать его я столкнулся с проблемой, что функция (onLazyLoad) вызывается только один раз, в фазе onInit()перед загрузкой данных с сервера.

Я могу отменить это, добавив [lazyLoadOnInit]="false", но это приводит к тому, что функция отложенной загрузки вообще не вызывается.Я надеялся, что смогу вызвать функцию загрузки, изменив свойство [totalRecords] при загрузке данных, но это также не вызывает функцию.

Я не могу найти никакую другую функцию в коде таблицы PrimeNG , которую можно использовать для запуска (onLazyLoad), или я что-то упустил?


Код

public ngOnInit(): void {
  this.cars$ = this.carService.entities$; // = []
  this.carService.getAll(); // = [Car, Car, Car, Car] OR []
}

this.carService.entities$ имеет значение по умолчанию [] и заполняется результатом функции getAll() (это также может быть [], если естьрезультатов нет)


Я воспроизвел мою проблему в a StackBlitz .Здесь вы можете видеть, что данные никогда не показываются, потому что (onLazyLoad) вызывается только в первый раз, когда данные пусты.

Обратите внимание, что я использую Angular Async pipe для передачи данных в мой компонент.Это означает, что мне нужно проверить изменения в функции ngOnChanges().

Ответы [ 2 ]

1 голос
/ 15 марта 2019

Просто обновите app.template следующим образом:

<ng-container *ngIf="cars$ | async as data">
  <table-component [data]="data"></table-component>
</ng-container>

Кажется, что p-таблица lasyload не срабатывает при изменении данных ??, даже когда свойство данных изменяется с undefined на object(arry)

stackblitz??

Обновлено

Без асинхронного канала получить данные

  public ngOnInit(): void {
    this.carService.getAll().subscribe(data => this.data = data);
  }

Метод ngOnChanges

  public ngOnChanges(change: SimpleChanges): void {
    if(change.data) {
      if (change.data.currentValue) {
      this.datasource = change.data.currentValue;
      this.totalRecords = Array.isArray(change.data.currentValue) ? change.data.currentValue.length : 0;
      this.cars = this.datasource.slice(0, 10); // row number
      this.loading = false;
      }
    }
  }

В этой статье объясняется, как использовать асинхронный канал и обнаружение изменений

stackblitz ??

0 голосов
/ 19 марта 2019

Благодаря malbarmawi Мне удалось обновить таблицу новыми записями. Единственная проблема, которая все еще сохраняется, заключается в том, что отложенная загрузка была вызвана только onInit() таблицы. Это было слишком рано, так как данные еще не были загружены.

Так что мне нужно было найти способ вызвать ленивую загрузку. Я заметил, что методы таблицы являются общедоступными, поэтому я мог вставить таблицу как @ViewChild и сам запустить отложенную загрузку.

/**
 * A reference to the primeng table. Since all of it's methods are public we can
 * directly access the methods we need to trigger lazy loading correctly.
 */
@ViewChild(Table)
private tableRef: Table;

public ngOnChanges(change: SimpleChanges): void {
   if(change.data && change.data.currentValue) {
     this.datasource = change.data.currentValue;
     this.totalRecords = Array.isArray(change.data.currentValue) ? change.data.currentValue.length : 0;

     // Trigger lazy loading
     this.tableRef.onPageChange({ first: 0, rows: this.rows });
   }
}

Поскольку у меня теперь ленивая загрузка, я также могу реализовать виртуальный скроллер, чтобы улучшить производительность таблицы и сделать возможным работу с моими 400.000 записями.

Для этого мне нужно было только обновить свойства таблиц (обратите внимание на виртуальные свойства):

<p-table [columns]="cols" [value]="cars" [scrollable]="true" [rows]="rows" [scrollHeight]="scrollHeight" [virtualRowHeight]="rowHeight" [virtualScroll]="true" [lazy]="true" (onLazyLoad)="loadCarsLazy($event)"  [totalRecords]="totalRecords" [loading]="isLoading"></p-table>

Полностью работающий пример этого кода можно найти на stackblitz

...