如何使用 Angular2+ 动态替换 Data Table 中的所有列?
How to replace all the columns dynamically in Data Table using Angular2+?
我要求在 changes/event 发生在数据 Table 之外时替换所有列。
数据 table 首次显示 selected 列(来自事件)。如果我 select 第二个它不显示,但 dtOptions 中的列已更改但不显示。我认为清除视图是问题,但我尝试使用 destroy 它不适合我。有人请帮助我实现这一目标。
HTML代码:
<div id="data-table-grid-slide">
<table datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" class="row-border hover"></table>
</div>
Angular 数据代码Table:
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。在此示例中,名为 columnsDataObj
和 dataUrl
的变量将动态变化。它应该反映在数据中 table。如果您需要更多详细信息,请告诉我:
https://stackblitz.com/edit/angular-datatables-gitter-4tavmk?file=app/app.component.ts
您还需要从模板中“销毁”dtOptions 和之前的 table,还必须确保您的模板在更改完成时通知,这是主要更改:
先把你之前的DT彻底毁掉,我加了个flag叫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 通知更改。
您的示例按预期工作:
我要求在 changes/event 发生在数据 Table 之外时替换所有列。
数据 table 首次显示 selected 列(来自事件)。如果我 select 第二个它不显示,但 dtOptions 中的列已更改但不显示。我认为清除视图是问题,但我尝试使用 destroy 它不适合我。有人请帮助我实现这一目标。
HTML代码:
<div id="data-table-grid-slide">
<table datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" class="row-border hover"></table>
</div>
Angular 数据代码Table:
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。在此示例中,名为 columnsDataObj
和 dataUrl
的变量将动态变化。它应该反映在数据中 table。如果您需要更多详细信息,请告诉我:
https://stackblitz.com/edit/angular-datatables-gitter-4tavmk?file=app/app.component.ts
您还需要从模板中“销毁”dtOptions 和之前的 table,还必须确保您的模板在更改完成时通知,这是主要更改:
先把你之前的DT彻底毁掉,我加了个flag叫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 通知更改。
您的示例按预期工作: