【问题标题】:How to replace all the columns dynamically in Data Table using Angular2+?如何使用Angular2+动态替换数据表中的所有列?
【发布时间】:2020-01-20 15:10:30
【问题描述】:

我要求在数据表之外发生更改/事件时替换所有列。

数据表首次显示选定的列(来自事件)。如果我选择第二个它不显示但 dtOptions 中的列被更改但它不显示。我认为清除视图问题,但我尝试使用破坏它不适合我。请有人帮助我实现这一目标。

HTML 代码:

<div id="data-table-grid-slide">
    <table datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" class="row-border hover"></table>
</div>

DataTable 的 Angular 代码:

import {Component, ViewChild, OnInit, Input, AfterViewInit, OnDestroy, Output, EventEmitter} from '@angular/core';
import { DataTableDirective } from 'angular-datatables';
import { Subject } from 'rxjs';
import { ColumnObject } from '../data-tables-net/model/data-tables-model';
import { HttpClient } from '@angular/common/http';
import { DtServiceService} from '../data-tables-net/dt-service.service';
import { WindowRef} from '../services/WindowRef';

declare var $;
@Component({
  selector: 'app-data-tables-net',
  templateUrl: './data-tables-net.component.html',
  styleUrls: ['./data-tables-net.component.css']
})
export class DataTablesNetComponent implements OnInit, AfterViewInit, OnDestroy {
  @ViewChild('dataTable', {static: true}) table;
  @ViewChild(DataTableDirective, {static: false}) dtElement: DataTableDirective;

  dataTableColumn: Array<any> = [];
  dtOptions: DataTables.Settings = {};
  @Input() dataTableGrid: boolean;
  @Input() tableShow: boolean;
  @Output() tableShowChange = new EventEmitter<boolean>();
  @Output() dataTableGridChange = new EventEmitter<boolean>();

  dtTrigger: Subject<any> = new Subject();

 // editor: any;
  columnObject: ColumnObject = {
      title: '',
      data: ''
  };
  constructor(private http: HttpClient, private dtServiceService: DtServiceService, private winRef: WindowRef) { }

  ngOnInit() {
    this.dataTableGrid = true;
    this.initDt();
  }
  ngAfterViewInit(): void {
    // This method get called on pencil click of model in Data Model Visuvalizer
    this.winRef.modelClick$.subscribe((modelObjAttributes) => {
      this.dataTableGrid = true;
      this.tableShow = false;
      this.tableShowChange.emit(this.tableShow);
      this.dataTableGridChange.emit(this.dataTableGrid);
      console.log('modelObjAttributes', modelObjAttributes);
      // tslint:disable-next-line: max-line-length
     // this.dtOptions.columns =  [{title: 'id', data: 'id'}, {title: 'name', data: 'name'}, {title: 'item code', data: 'item code'}, {title: 'addr', data: 'addr'}];
      if (this.dtOptions.columns) {
        // this.dtOptions.destroy = true;
       //  delete this.dtOptions.columns;
       



this.reRenderDataTable();
       //  console.log('columns', this.dtOptions.columns);
         this.initDt();
         this.dtOptions.columns =   this.getModelDetails(modelObjAttributes);
       //  console.log(this.dtOptions.columns);
         this.dtTrigger.next();
      } else {
        this.dtOptions.columns =   this.getModelDetails(modelObjAttributes);
        console.log(this.dtOptions.columns);
        this.dtTrigger.next();
        // this.dtOptions.destroy = true;
      }
    //  delete this.dtOptions.columns;


    });
  }
  initDt() {
    this.dtOptions = {
      // ajax: 'data/data.json',
      // columns: [{title: 'Column1', data: 'column1'}],
      paging: true,
      searching: true,
      ordering: true,
      info:     false,
      responsive: true,
      destroy: true
    };
    }

  ngOnDestroy(): void {
    // Do not forget to unsubscribe the event
    this.dtTrigger.unsubscribe();
  }

  // This method used to get the details of model on clicking of pencil icon
  getModelDetails(modelDetailsObj) {
    return this.convertModelAttributesToDataTable(modelDetailsObj.options);
    // this.getModelDetailsFromService(modelDetailsObj.id);
  }

// This method is used to  call the service to get the selected Models / Schema details from Database
 getModelDetailsFromService(schemaId): void {
  this.dtServiceService.getSelectedSchema(schemaId).subscribe(data => {
    console.log(data);
  },
  error => {
    console.log('Data is not getting');
  });
}

  // This method used to form the schema data for Data Table
  convertModelAttributesToDataTable(attributesObject) {
    this.dataTableColumn = [];
    // delete this.dtOptions.columns;

    for (const [index, obj] of attributesObject.entries()) {
      if (obj) {
          this.columnObject = { title: obj.text, data: obj.text};
          console.log('columnObject', this.columnObject);
          this.dataTableColumn.push(this.columnObject);
        //  console.log(this.dtOptions);
      }
    }
   // this.dtTrigger.next();
    return this.dataTableColumn;
  }
  // This method used re-render the data table with updated data's
  reRenderDataTable(): void {
    this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
      // Destroy the table first
      // dtInstance.destroy();
      // Call the dtTrigger to rerender again
      this.dtTrigger.next();
    });
  }

}

我已经为我的要求创建了 stackblitz。在此示例中,名为 columnsDataObjdataUrl 的变量将动态变化。它应该反映在数据表中。如果您需要更多详细信息,请告诉我:

https://stackblitz.com/edit/angular-datatables-gitter-4tavmk?file=app/app.component.ts

【问题讨论】:

  • 当您想要动态设置列时,您需要根据更改重新创建数据表。看看这个stackoverflow.com/questions/32487401/…
  • 据我了解,您想要的是在触发某些操作时更改表的列,这样做只需更改 dataTableOptions,如果您提供对代码和所需内容的更多了解我可以查看代码并帮助您解决问题
  • @Stratubas - 我无法使用上面的代码创建 stackbilitz,因为这与我项目中的其他组件有很多依赖关系。但我只会为我的要求创建 stackbilitz。
  • @NavruzbekNoraliev - 如果您看到我的代码,我正在更改数据表选项,但它正在更改,但它反映了视图。如果我检查更新的选项,它会变得正确。请告诉我或提供任何样品。
  • @bagya 这是重新创建数据表的最佳解决方案

标签: javascript angular datatable angular-datatables


【解决方案1】:

您还需要从模板中“销毁” dtOptions 和上一个表,还必须确保您的模板在更改完成时通知,这是主要更改:

首先彻底销毁你之前的DT,我添加了一个名为dtRendered的标志:

dtRendered = true;
<table *ngIf="dtRendered" datatable [dtOptions]="dtOptions" class="row-border hover">

此外,在您的更新方法中,您必须确保所有内容都被销毁并再次初始化:

updateData() {
  // destroy you current configuration
  this.dtRendered = false
  this.dtOptions = {
    data: this.jsonData1.data,
    columns: this.columnsDataObj1
  };
  // make sure your template notices it
  this.cdr.detectChanges();
  // initialize them again
  this.dtRendered = true
  this.cdr.detectChanges();
}

需要this.cdr.detectChanges() 调用,以便lifecycle-hook 通知更改。

这是您的示例按预期工作:

https://stackblitz.com/edit/how-to-replace-all-the-columns-dynamically-in-data-table?file=app/app.component.ts

【讨论】:

  • 这个例子对我帮助很大。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-05
  • 2019-09-18
  • 2022-01-28
  • 1970-01-01
  • 1970-01-01
  • 2019-07-24
  • 1970-01-01
相关资源
最近更新 更多