无法使用Angular Datatable重新初始化DataTable

时间:2019-06-25 07:42:03

标签: jquery html angular typescript datatable

我有一个带有简单CRUD功能的Angular应用程序。我已经使用静态HTML表测试了我的数据,并且可以正常工作。现在,我正在使用一个称为Angular数据表的数据表框架。

链接:https://l-lin.github.io/angular-datatables/#/welcome

我可以创建阅读删除一条记录,但是执行此操作后,我会收到类似以下错误:

  

DataTables警告:表ID = DataTables_Table_0-无法重新初始化   数据表。有关此错误的更多信息,请参见   http://datatables.net/tn/3

我已经尝试了几种解决方案,例如它提供的链接以及其他类似这样的堆栈溢出问题:

Getting error in Angular 5 Datatables: cannot reinitialise DataTable

https://l-lin.github.io/angular-datatables/#/basic/angular-way

https://l-lin.github.io/angular-datatables/#/advanced/rerender

这是我在 car-component.js 中的代码,我对所有HTTP调用都使用了 car-services.js

import { Component, OnInit } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { CarService } from '../services/carservices/car.service';
import { CarVM } from '../viewmodels/car/car-vm';
import { Subject } from 'rxjs';
import { DataTableDirective } from 'angular-datatables';

@Component({
  selector: 'app-car',
  templateUrl: './car.component.html',
  styleUrls: ['./car.component.css']
})
export class CarComponent implements OnInit {

  FormCar: any;
  countrecords: any;
  Carid: number = 0;
  dtTrigger: Subject<any> = new Subject();
  dtElement: DataTableDirective;
  allCars: CarVM[];
  dtOptions: DataTables.Settings = {};

  constructor(private formbuilder: FormBuilder, private carservice: CarService) { }

  ngOnInit() {

    this.dtOptions = {
      pagingType: 'full_numbers',
      pageLength: 5,
    };

    this.GetCar();
    this.GetCarCount();

    this.FormCar = this.formbuilder.group({
      CarId: ['', Validators.required],
      Brand: ['', Validators.required],
      Model: ['', Validators.required],
      Color: ['', Validators.required],
      TopSpeed: ['', Validators.required],
    });
  }

  AddCar(CarVM: CarVM) {
    CarVM.CarId = this.Carid;
    this.carservice.CreateCar(CarVM).subscribe(() => {
      this.GetCar();
      this.GetCarCount();
      this.Reset();
      this.Carid = 0;
    })
  }

  GetCar() {
    this.carservice.getAllCars().subscribe(res => {
      this.allCars = res;
      this.dtTrigger.next();
    })
  }

  GetCarCount() {
    this.countrecords = this.carservice.getCount();
  }

  EditCar(car: CarVM) {
    this.carservice.updateCar(car).subscribe(Response => {
      this.Carid = Response.CarId;
      this.FormCar.controls['Brand'].setValue(Response.Brand);
      this.FormCar.controls['Model'].setValue(Response.Model);
      this.FormCar.controls['Color'].setValue(Response.Color);
      this.FormCar.controls['TopSpeed'].setValue(Response.TopSpeed);
    })
  }

  DeleteCar(CarId: string) {
    if (confirm("Are you sure?")) {
      this.carservice.deleteCar(CarId).subscribe(() => {
        this.GetCar();
        this.GetCarCount();
      })
    }
  }

  Reset() {
    this.FormCar.reset();
  }
}

这是我在车上的HTML页面:

<table datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" class="row-border hover">
  <thead>
    <tr>
      <th>Id</th>
      <th>Brand</th>
      <th>Model</th>
      <th>Color</th>
      <th>Speed</th>
      <th>Action</th>
    </tr>
  </thead>
  <tbody>
    <tr *ngFor="let car of allCars">
      <td>{{car.carId}}</td>
      <td>{{car.brand}}</td>
      <td>{{car.model}}</td>
      <td>{{car.color}}</td>
      <td>{{car.topSpeed }}</td>
      <td>
        <button type="button" class="btn btn-danger mr-1" (click)="DeleteCar(car.carId)">Delete</button>
      </td>
    </tr>
  </tbody>
</table>

注意:

我使用的是 Angular 版本,而不是 JQuery 版本!

有人可以指出我正确的方向吗?

3 个答案:

答案 0 :(得分:1)

以上答案@Adrita Sharma不适用于我,它抛出了此错误

core.js:9110错误TypeError:无法读取未定义的属性'dtInstance'

所以我添加了

@ViewChild(DataTableDirective,{static:false})

成功了

import { Component, ViewChild, OnInit } from '@angular/core';
import { DataTableDirective } from 'angular-datatables';

export class AttendancePage implements OnInit {

@ViewChild(DataTableDirective, {static: false})
dtElement: DataTableDirective;

isDtInitialized:boolean = false

还有用于初始化数据表的内部函数

if (this.isDtInitialized) {
    this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
        dtInstance.destroy();
        this.dtTrigger.next();
    });
} else {
    this.isDtInitialized = true
    this.dtTrigger.next();
}

答案 1 :(得分:0)

您需要销毁数据表实例,然后再次触发它。

您可以创建如下函数:

log stream

import { DataTableDirective } from 'angular-datatables';

dtElement: DataTableDirective;

isDtInitialized:boolean = false

使用它,它将第一次进入else块并直接触发数据表。之后,刷新时,它将首先销毁数据表,然后触发。

答案 2 :(得分:0)

HTML

<div class="table-responsive">
                                            <table datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" 
                                                style="width: 99.5% !important;" class="table table-responsive-sm table-bordered table-striped table-sm">
                                            <thead>
                                                <tr>
                                                <th>Client ID</th>
                                                <th>Client Name</th>
                                                <th>Client Phone</th>
                                                <th>Join Date</th>
                                                <th>Email</th>
                                                <th>Is Active</th>
                                                <th>Operation</th>
                                                </tr>
                                            </thead>
                                            <tbody *ngIf="modelList && modelList?.length != 0">
                                                <tr *ngFor="let m of modelList">
                                                <td>{{ m.ClientID }}</td>
                                                <td>{{ m.ClientName }}</td>
                                                <td>{{ m.ClientPhone }}</td>
                                                <td>{{ m.JoinDate | date : "MMM d, y" }}</td>
                                                <td>{{ m.Email}}</td>
                                                <td>
                                                        <div class="btn-group project-list-ad" *ngIf="m.IsActive">
                                                                <button class="btn btn-white btn-xs">Active</button>
                                                        </div>

                                                        <div class="btn-group project-list-ad-rd" *ngIf="!m.IsActive">
                                                                <button class="btn btn-white btn-xs">Unactive</button>
                                                        </div>
                                                </td>
                                                <td>
                                                    <button class="btn btn-pill btn-dark" type="button" (click)='editbuttonClick(m.ClientID)'>
                                                    <i class="fa fa-file-o fa-sm mt-1"></i>&nbsp;Edit
                                                    </button>
                                                </td>
                                                </tr>
                                            </tbody>
                                            <tbody *ngIf="!modelList || modelList?.length == 0">
                                                <tr>
                                                <td colspan="3" class="no-data-available">No data!</td>
                                                </tr>
                                            <tbody>
                                            </table>
                                        </div>

类型脚本代码 对于Angular 8

@ViewChild(DataTableDirective, {static : false})
dtElement: DataTableDirective;

dtOptions: DataTables.Settings = {};
dtTrigger: Subject<ClientList> = new Subject();

在类上实现AfterViewInit

loadAllData() {

const that = this;


this.dtOptions = {
  pagingType: 'full_numbers',
  pageLength: 10,
  serverSide: true,
  processing: true,
  ajax: (dataTablesParameters: any, callback) => {
    that._http
      .post<DataTablesResponse>(
        //'https://angular-datatables-demo-server.herokuapp.com/',
        this.env.apiUrl + 'api/setup/ClientList_SelectAll_Grid',
        dataTablesParameters, {}
      ).subscribe(resp => {
        //console.log(dataTablesParameters);
        that.modelList = resp.data;


        callback({
          recordsTotal: resp.recordsTotal,
          recordsFiltered: resp.recordsFiltered,
          data: []
        });
      });
  },
  columns: [{ data: 'ClientID' }, { data: 'ClientName' }, { data: 'ClientPhone' }, { data: 'JoinDate' }, { data: 'Email' }, { data: 'IsActive' }, { defaultContent: '', orderable: false }]
};



 }

 ngAfterViewInit(): void {
    this.dtTrigger.next();
 }



 rerender(): void {

this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
  // Destroy the table first
  dtInstance.destroy();
  // Call the dtTrigger to rerender again
  this.dtTrigger.next();
});


}

full example of Angular DataTables Server side pagination & Sorting