как я могу обновить количество столбцов в angular-datatables с рендерингом на стороне сервера. версия 6.0.0 или выше

У меня возникли проблемы с получением моего angular-datatable для отображения нового списка столбцов после повторной визуализации. Я следовал примеру, показанному в документах, для повторной визуализации, и я могу заставить таблицу перерисовываться. Я могу манипулировать некоторыми функциями, такими как поиск и pageLength, но по какой-то причине я не могу изменить свои столбцы.

У меня есть очень глубокий набор данных, из-за которого моя таблица выглядела бы ужасно, если бы я отображал все столбцы сразу, поэтому я хотел бы дать пользователям возможность выбирать, какие столбцы они видят.

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

У кого-нибудь была эта проблема раньше?

Функция ререндера:

rerender(): void {
this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
  dtInstance.destroy();
  // these work
  this.dtOptions.searching = true;
  this.dtOptions.pageLength = 2;
  // these do not
  this.dtOptions.columns = newColumnList;
  this.dtOptions.columns[some-index].visible = false;
  this.dtTrigger.next();
});}

Начальные dtOptions:

this.dtOptions = {
  searching: false,
  pagingType: 'full_numbers',
  pageLength: 10,
  retrieve: true,
  serverSide: true,
  processing: true,
  language: {
    zeroRecords: 'Nothing Found'
  },
  ajax: (dataTablesParameters: any, callback) => {
    const payload = this.passFilterService.processPagination(this.filter, dataTablesParameters);
    this.http
      .post<any>(
        environment.api + '/things/list',
        {payload: payload}, {}
      ).subscribe(resp => {
        if (resp.data.data === null) {
          resp.data.data = 0;
        }
      callback({
        recordsFiltered: resp.data.totalCount,
        data: resp.data.data,
        recordsTotal: resp.data.totalCount
      });
    });
  },
  columns: this.tableColumns
};

Начальные столбцы (ограниченное количество полей):

tableColumns = [
{
  title: 'Customer',
  data: 'Id',
  render: function(data) {
    return `<a href="/pass/` + data + `" class="cursor-pointer actionView" title="View">Action</a>`;
  }
}, {
  title: 'Created',
  data: 'createdAt',
  orderable: true,
  visible: true,
}, {
  title: 'Updated',
  data: 'updatedAt',
  orderable: true,
  visible: true,
}, {
  title: 'Disabled',
  data: 'isVoided',
  orderable: true,
  visible: true,
}
];

Реализация таблицы:

<table datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" class="row-border hover">
</table>

person J.Langford    schedule 13.07.2018    source источник
comment
Удачи с этим? Я столкнулся с той же проблемой...   -  person Muhammad Ali    schedule 18.09.2018


Ответы (1)


Я столкнулся с той же проблемой, потратил часы на ее отладку, пока не нашел что-то, что сработало для меня. Я советую выделить конфигурацию DT в независимый объект, который можно загружать отдельно. После того, как вы обновите параметры DT и любую другую конфигурацию, вы можете использовать функции ниже, чтобы перезагрузить все DT, соответственно уничтожив и перезагрузив его;

async rerender(newSettings?: DataTables.Settings) {
    try {
        this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
            if (newSettings) {
                // FIX To ensure that the DT doesn't break when we don't get columns
                if (newSettings.columns && newSettings.columns.length > 1) {
                    dtInstance.destroy();
                    this.dtOptions = Promise.resolve(newSettings);
                    this.displayTable(this.dtTableElement);
                }
            }
        });
    } catch (error) {
        console.log(`DT Rerender Exception: ${error}`);
    }
    return Promise.resolve(null);
}

Эта функция вызывает приведенную ниже функцию, чтобы фактически уничтожить DT и перерендерить его.

private displayTable(renderIn: ElementRef): void {
    this.dtElement.dtInstance = new Promise((resolve, reject) => {
        Promise.resolve(this.dtOptions).then(dtOptions => {
            // Using setTimeout as a "hack" to be "part" of NgZone
            setTimeout(() => {
                $(renderIn.nativeElement).empty();
                var dt = $(renderIn.nativeElement).DataTable(dtOptions);
                // this.dtTrigger.next();
                resolve(dt);
            });
        }).catch(error => reject(error));
    });
}

Я удалил выполнение dtTrigger из функции реконструкции, поскольку она выполнялась дважды.

dtTableElement определяется как @ViewChild('dtTableElement') dtTableElement: ElementRef;, где HTML содержит соответствующую ссылку на таблицу данных как:

<table #dtTableElement datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" class="table table-striped row-border hover" width="100%"></table>

person Cyrus Mushier    schedule 11.10.2018