【问题标题】:Getting error in Angular 5 Datatables: cannot reinitialise DataTable在 Angular 5 Datatables 中出现错误:无法重新初始化 DataTable
【发布时间】:2018-03-12 10:00:47
【问题描述】:

我正在从事基于角度的项目。我正在使用数据表来显示数据。当我尝试对表进行一些修改时,出现以下错误。

DataTables 警告:table id=DataTables_Table_0 - 无法重新初始化 DataTable。有关此错误的更多信息,请参阅http://datatables.net/tn/3

【问题讨论】:

    标签: datatables angular5


    【解决方案1】:

    我认为这是因为您在 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();     
      });
    }
    

    【讨论】:

    • 是的,此解决方案有效。欲了解更多信息,请访问此链接l-lin.github.io/angular-datatables/#/advanced/rerender
    • 销毁导致表闪烁。让我以角度方式工作让我抓狂
    • @ppumkin 是的。闪烁很烦人。 it is because you are using [dtTrigger]="dtTrigger"为什么会出现这个问题?
    • 不幸的是,问题是它自己的数据表。 Destroy 从字面上删除 DOM 并收集浏览器垃圾,然后 DT 重新绘制从新鲜。 (这会导致闪烁,我还没有找到一个优雅的 [强调优雅 - 我找到了一些 hacky 方法,我讨厌它] 解决方案来绕过这个)我已经转向 Material 并使用他们的 DataTable .. 工作起来更容易老实说,在 Angular 6 中。我认为 Datatables 落后了,这很可惜,因为我非常喜欢它。
    • @PiotrKula 我被 angular-datatables 和 destroy 方法卡住了,闪烁很糟糕,您介意分享您使用的技巧吗?
    【解决方案2】:

    我通过删除 *.ts 文件中的以下代码解决了这个问题:

    dtOptions: DataTables.Settings = {};
     this.dtOptions = {
    };
    

    【讨论】:

    • 您是如何通过删除这些行使其工作的?我的还是这样
    • @Code Lover:不适用于您的解决方案。你能分享一些sn-p吗?
    • 删除这些行后应该如何工作?这些是主要配置,不是吗?请分享一些代码
    【解决方案3】:

    我在 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'});
        });
    }
    

    【讨论】:

      【解决方案4】:

      我已经在 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>
      

      【讨论】:

        【解决方案5】:

        我已经删除了这个下面的函数,它对我有用。请按照以下步骤操作

        1. 在您的 Angular 项目中,转到此位置 'node_modules\datatables.net\js'。
        2. 您可以在此处看到一个名为“jquery.datatable.js”的 js 文件。

        1. 打开文件并搜索“_fnLog”。 _fnLog 是一个函数。
        2. 只需注释 _fnLog 函数的整个代码并保存您的文件。您的问题将得到解决。

        【讨论】:

          【解决方案6】:

          我遇到了类似的问题,唯一需要补充的是:

            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
                });
           }
          

          【讨论】:

            【解决方案7】:

            很简单。

            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%">
            

            最大的战斗是与无知的战争!

            【讨论】:

              猜你喜欢
              • 2015-11-04
              • 2015-05-30
              • 1970-01-01
              • 1970-01-01
              • 2022-01-25
              • 2019-11-07
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多