【发布时间】:2018-03-12 10:00:47
【问题描述】:
我正在从事基于角度的项目。我正在使用数据表来显示数据。当我尝试对表进行一些修改时,出现以下错误。
DataTables 警告:table id=DataTables_Table_0 - 无法重新初始化 DataTable。有关此错误的更多信息,请参阅http://datatables.net/tn/3
【问题讨论】:
标签: datatables angular5
我正在从事基于角度的项目。我正在使用数据表来显示数据。当我尝试对表进行一些修改时,出现以下错误。
DataTables 警告:table id=DataTables_Table_0 - 无法重新初始化 DataTable。有关此错误的更多信息,请参阅http://datatables.net/tn/3
【问题讨论】:
标签: datatables angular5
我认为这是因为您在 Angular DataTables 中使用 [dtTrigger]="dtTrigger" 并在同一页面上重新呈现表格。如果你有这个问题你应该使用下面的技巧来处理dtTrigger
<table datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" class="table">
确保不要在ngOnInit() 上使用this.dtTrigger.next()
ngAfterViewInit(): void {
this.dtTrigger.next();
}
第二次使用时重新渲染
rerender(): void {
this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
dtInstance.destroy();
this.dtTrigger.next();
});
}
【讨论】:
it is because you are using [dtTrigger]="dtTrigger"为什么会出现这个问题?
我通过删除 *.ts 文件中的以下代码解决了这个问题:
dtOptions: DataTables.Settings = {};
this.dtOptions = {
};
【讨论】:
我在 Angular7 和 Bootstrap4 中使用 DataTable
第一步:安装包
npm i angular-datatables@6 datatables.net@1.10.19 datatables.net-dt@1.10.19 --save
第二步:在angular.json
“样式”:[ “./node_modules/datatables.net-dt/css/jquery.dataTables.css” ], “脚本”:[ “node_modules/datatables.net/js/jquery.dataTables.js” ],
第三步:内部app.module.ts
import { DataTablesModule } from 'angular-datatables';
imports: [
.......
DataTablesModule
]
第四步:Inside html
<table datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" >...</table>
第五步:Inside ts
import { Component, OnInit, AfterViewInit, OnDestroy, ViewChild } from '@angular/core';
declare var jQuery:any;
import { DataTableDirective } from 'angular-datatables';
import { Subject } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../environments/environment';
export class YourComponent implements OnInit, AfterViewInit, OnDestroy {
@ViewChild(DataTableDirective) dtElement: DataTableDirective;
dtOptions: DataTables.Settings = {};
dtTrigger: Subject<any> = new Subject();
ajxrequrl: string = environment.hostUrl + '/api/userList';
start: number = 0; length: number = 10; draw: number = 1;
postparams = {};
constructor( private _http: HttpClient ) { }
getListData(filterData, t) {
//console.log(filterData);
var zone = (filterData.zone != undefined ) ? filterData.zone : 0 ;
var state = (filterData.state != undefined ) ? filterData.state : 0 ;
var studentType = (filterData.studentType != undefined ) ? filterData.studentType : 0 ;
var status = (filterData.status != undefined ) ? filterData.status : 0 ;
var grade = (filterData.grade != undefined ) ? filterData.grade : 0 ;
var startDate = (filterData.startDate != undefined ) ? filterData.startDate : 0 ;
var endDate = (filterData.endDate != undefined ) ? filterData.endDate : 0 ;
const that = this;
this.dtOptions = {
pagingType: 'full_numbers',
pageLength: this.length,
displayStart: this.start,
autoWidth: false,
serverSide: true,
processing: true,
searching: true,
order: [],
columnDefs: [ {
'targets': [0], /* column index [0,1,2,3]*/
'orderable': false, /* true or false */
}],
ajax: (dataTablesParameters: any, callback) => {
var orderColumn = ''; var orderBy = ''; var order = 0;
if(dataTablesParameters.order.length) {
var sortarr = ['classId', 'full_name', 'age', 'status', 'grade', 'zone', 'state', 'type', ... <all columns>];
orderColumn = sortarr[dataTablesParameters.order[0].column];
orderBy = dataTablesParameters.order[0].dir;
order = 1;
}
/* Sending data through GET */
/*
that.getparams = "?start="+dataTablesParameters.start
+"&length="+dataTablesParameters.length
+"&order="+order
+"&orderColumn="+orderColumn
+"&orderBy="+orderBy
+"&zone="+zone
+"&state="+state
+"&studentType="+studentType
+"&status="+status
+"&grade="+grade
+"&startDate="+startDate
+"&endDate="+endDate;
//+"&search="+encodeURI(dataTablesParameters.search.value);
that._http.get(that.ajxrequrl + that.getparams, {}).subscribe(resp => {
*/
/* Sending data through POST */
that.postparams = {
start: dataTablesParameters.start,
length: dataTablesParameters.length,
order: order,
orderColumn: orderColumn,
orderBy: orderBy,
search: dataTablesParameters.search,
//filterData: filterData
zone: zone,
state: state,
studentType: studentType,
status: status,
grade: grade,
startDate: startDate,
endDate: endDate
};
//jQuery('.dataTables_filter label input').attr("placeholder", "CL Contract ID or Customer Name or Case No");
//jQuery('.dataTables_filter label input').css({'width': '350px', 'display': 'inline-block'});
this._http.post( that.ajxrequrl, that.postparams, {} ).subscribe(
resp => {
that.listData = resp['data'];
that.start = resp['start'];
callback({
recordsTotal: resp['recordsTotal'],
recordsFiltered: resp['recordsFiltered'],
data: []
});
},
error => {
console.log(error);
}
);
}
};
if(t == 1) {
this._othercaseService.filterList(filterData).subscribe(
(resp) => {
this.rerender();
this.listData = resp['data'];
if(resp['status'] == 0) {
//this.resetForm();
}
});
}
}
ngOnDestroy(): void {
// Do not forget to unsubscribe the event
this.dtTrigger.unsubscribe();
}
rerender(): void {
this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
// Destroy the table first
dtInstance.destroy();
// Call the dtTrigger to rerender again
this.dtTrigger.next();
});
}
ngAfterViewInit() {
this.dtTrigger.next();
this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
dtInstance.on( 'draw.dt', function () {
if(jQuery('.dataTables_empty').length > 0) {
jQuery('.dataTables_empty').remove();
}
});
});
}
onSubmit(formData: NgForm) { // This function is called after a filter form searched
this.getListData(formData, 1);
}
resetForm(pageStart: number = 1) {
if(!pageStart) this.start = 0;
}
deleteUser(pkId) {
/* After Delete code */
this.getListData({}, 0);
}
}
第 6 步:在您的 controller api call 内部
module.exports.userList = (req, res, next) => {
let reqData = req.body;
var sql = 'SELECT .... FROM ....';
/* ----- started changes for filter (just example)----- */
sql = (reqData.grade) ? sql + ' AND grade = "' + reqData.grade + '"' : sql;
sql = (reqData.status) ? sql + ' AND status = "' + reqData.status + '"' : sql;
............
/* ----- end of changes for filter ----- */
/* ----- started changes for pagination ----- */
sql = (!reqData.orderColumn || !reqData.orderBy) ? sql + ' ORDER BY pkId DESC' : sql+ ' ORDER BY ' + reqData.orderColumn + ' ' + reqData.orderBy;
var start = (reqData.start) ? reqData.start : 0;
var length = (reqData.length) ? reqData.length : 10;
/* ----- end of changes for pagination ----- */
mysql.conn.query(sql, (err, rows) => {
if(err) {
res.json({'status': 1, 'data': [], 'message': 'No result found'});
}
var len = rows.length;
if(len) {
sql += ' LIMIT ' + start + ',' + length;
mysql.conn.query(sql, (err, rows1) => {
if (!err) {
res.json({'status': 0, 'data': rows1, 'recordsTotal': len, 'recordsFiltered': len, 'start': start, 'draw': 1});
} else {
res.json({'status': 1, 'data': [], 'message': 'No result found'});
}
});
} else res.json({'status': 1, 'data': [], 'message': 'No result found'});
});
}
【讨论】:
我已经在 Angular 7 中尝试过这个并且它有效.. 运行时数据表已更改
.ts 文件
import { Component, AfterViewInit, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { DataTableDirective } from 'angular-datatables';
@Component({
selector: 'app-selector',
templateUrl: 'app-selector.component.html'
})
export class CustomRangeSearchComponent implements AfterViewInit, OnDestroy, OnInit {
@ViewChild(DataTableDirective, {static: false})
datatableElement: DataTableDirective;
dtOptions: DataTables.Settings = {};
tableData = [];
ngOnInit(): void {
this.dtOptions = {
destroy: true,
ordering: true,
pagelength: 10,
pagingType: "full_numbers",
columnDefs: [{
targets: 0,
checkboxes:{
selectRow: true,
selected: true
}]
};
}
ngOnDestroy(): void {
$.fn['dataTable'].ext.search.pop();
}
ngAfterViewInit(): void {
this.dtTrigger.next();
}
getdata(){
//... get your response
this.tableData = response; //this should be in array
setTimeout(() => {
this.datatableElement.dtInstance.then((dtInstance: DataTables.Api) => {
dtInstance.draw();
});
});
}
}
.HTML 文件
<button class="btn btn-primary" (click)="getData()">Filter by ID</button>
<table datatable [dtOptions]="dtOptions" class="row-border hover"></table>
【讨论】:
我遇到了类似的问题,唯一需要补充的是:
ngAfterViewInit() {
this.dtTrigger.next();
}
在我的构造函数中:
this.options = {
multiple: true,
};
在 Html 声明中:
<table aria-describedby="Some interesting description" datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger"
<tbody>
<tr *ngFor="let item of data">
<td>{{ item }}</td>
</tr>
</tbody>
</table>
在获取数据的方法中:
someDataMethod(): void {
this.dataAjaxService.someMethod(id).subscribe((data: any) => {
this.data = data;
}, error => {
//handle error
});
}
【讨论】:
很简单。
onDestroy(){
this.dtElements.forEach((dtElement: DataTableDirective,index:number) => {
dtElement.dtInstance.then((dtInstance: any) => {
dtInstance.destroy(); // Before destroy
this.dtTrigger.next(); // Again trigger of method.
});
});
}
dtOptions:
this.dtOptions["new"] = {
paging: true,
fixedColumns: true,
order: [[1, "asc"]],
autoWidth: true,
language: {
"url": "assets/json/Turkish.json"
},
select: false,
responsive: true,
pagingType: 'full_numbers',
pageLength: 10,
retrieve:true, **This is important** };
HTML
<table datatable [dtOptions]="dtOptions['new']" [dtTrigger]="dtTrigger" class="row-border hover fixed_header"
style="width:100%">
<table datatable [dtOptions]="dtOptions['new']" [dtTrigger]="dtTrigger2" class="row-border hover fixed_header"
style="width:100%">
最大的战斗是与无知的战争!
【讨论】: