Angular 6 数据Tables - Table 项目 Appear/Disappear 排序或搜索
Angular 6 DataTables - Table Items Appear/Disappear Upon Sort or Search
我正在使用 Angular-DataTables 6.0(可在此处 https://l-lin.github.io/angular-datatables/#/welcome 找到)并且我 运行 遇到了一个反复出现的问题。添加或删除 table 项目时,记录在排序或搜索时消失或重新出现。这可能是因为 adding/deleting 是从数据表外部发生的吗?
我已经尝试添加“数据table="ng"”来修复许多其他建议,但这并没有改变任何东西。我还尝试添加一个重新渲染功能,但在那种情况下,我 运行 变成 'object unsubscribed' 我无法解决的错误。作为参考,一些类似的问题可以在这里找到:类似的例子包括:()
()
(https://github.com/l-lin/angular-datatables/issues/852)
这是我的代码:
HTML:
<table datatable="ng" [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" class="table table-hover" id="t1">
<thead>
<tr>
<th>
<button id="b5">Asset ID</button>
</th>
<th>
<button id="b5">Employee ID</button>
</th>
<th>
<button id="b5">Asset Type</button>
</th>
<th>View</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let a of assets; let i = index">
<td>{{ a.assetID }}</td>
<td>{{ a.currentUser }}</td>
<td>{{ a.assetType }}</td>
<td><button id="button1" (click)="viewAsset(a)"><i class="fas fa-search"></i></button></td>
<td><button id="b2" class="btn" (click)="scrapAsset(a)" (mouseenter)="buttonHover(i)" (mouseleave)="buttonHoverLeave(i)"><i class="{{buttonIconArray[i].text}}"></i></button></td>
</tr>
</tbody>
</table>
-elsewhere in the code-
<button class="btn" id="b1" (click)="addAsset()">Add New Asset</button>
TS
dtOptions: DataTables.Settings = {};
dtTrigger = new Subject();
addAsset()
{
this.confirmChanges = false;
//Create a new asset:
let a: Asset = {
assetID: this.assetID,
currentUser: this.currentUser,
assetType: this.dropdownMessage,
}
//send a notification to the user that owns the new asset
let notify: Notice = {
emplyID: a.currentUser,
notificationSource: "Asset",
details: "A new " + this.dropdownMessage + " was added to your assets.",
timeStamp: new Date()
}
//Add the asset to the server
this.AssetsService.addAsset(a)
.subscribe(asset => { this.assets.unshift(asset);
//All of the inputs need to be emptied
this.clearFields();
})
}
scrapAsset(a: Asset)
{
console.log("The ID is " , a.assetID)
//this.AssetsService.deleteAsset(this.currentAsset).subscribe()
this.confirmChanges = false;
//This deletes the asset from the back-end.
this.AssetsService.deleteAsset(a).subscribe(() => {
console.log('test')
this.assets = this.assets.filter(t => t !== a);
this.NotificationsService.addNotice(notify).subscribe();
this.clearFields(); });
}
dtActivate()
{
this.dtOptions = {
pagingType: 'full_numbers',
pageLength: 7,
order: (this.assets.assetType),
orderClasses: false,
};
this.AssetsService.getAssetsIT().subscribe((assetsImported) => {
this.assets = assetsImported;
this.parseData();
// Calling the DT trigger to manually render the table
this.dtTrigger.next();
});
}
这只是代码的一部分,所以如果您需要查看更多内容,请询问。感谢您提供的任何帮助!
这可行,但我仍在寻找更好的解决方案
setTimeout(function () {$(function () {$('#ng').DataTable();});}, 10);
你可以删除 ng,下面的代码解决了我的问题
<div class="container-fluid">
<div class="page-title">
<h4>Milk Types</h4>
</div>
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-block">
<a href="" class="btn btn-success" href='' [routerLink]="['/milk/create-milk']">
<i class="ti-zip pdd-right-5"></i>
<span>Add New Milk</span>
</a>
<div class="table-overflow">
<table class="table table-lg table-hover" datatable [dtTrigger]="dtTrigger" [dtOptions]="dtOptions">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Status</th>
<th>Price</th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let drink of data">
<td>
<div class="mrg-top-15">
<b class="text-dark font-size-16">{{ drink.id }}</b>
</div>
</td>
<td>
<div class="mrg-top-15">
<span class="text-info pdd-left-20"><b>{{ drink.name }}</b></span>
</div>
</td>
<td>
<div class="col-md-5">
<div class="toggle-checkbox toggle-success checkbox-inline">
<input type="checkbox" name="isEnabled" id="toggle4" [checked]="drink.isEnabled">
<label for="toggle4"></label>
</div>
</div>
</td>
<td>
<div class="mrg-top-15">
<span class="text-info"><b>KD {{ drink.price }}</b></span>
</div>
</td>
<td>
<div class="mrg-top-10 text-center">
<a href="" class="btn btn-warning">
<i class="ti-comment pdd-right-5"></i>
<span>Edit</span>
</a>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
import { Component, OnInit, Input, OnDestroy , ViewEncapsulation } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';
import { pipe, Subscription } from 'rxjs';
import { MilksItem, MilksDataSource } from './milks-datasource';
import { Subject } from 'rxjs';
@Component ({
templateUrl: 'milk.html'
})
export class MilkComponent implements OnInit {
dtOptions: DataTables.Settings = {};
subscription: Subscription;
data: MilksItem[] = [];
dtTrigger: Subject<MilksItem> = new Subject();
constructor(private db: AngularFireDatabase)
{
}
ngOnInit() {
this.dtOptions = {
pagingType: 'full_numbers'
};
this.subscription = this.db.list<MilksItem>('milkTypes').valueChanges().subscribe(d=>{
console.log('data streaming');
this.data = d;
this.dtTrigger.next();
});
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
this.dtTrigger.unsubscribe();
}
}
同样的问题困扰我很久了。在大量的堆栈溢出和文档之后,我找到了解决我的问题的解决方案。也许它对你也有帮助。
允许销毁数据表
ngOnInit() {
this.dtOptions = {
destroy: true,
...
};
...
}
接收新项目的方法(在编辑、插入、添加...后调用)。
onReceived(items){
let isFirst = this.items.length === 0;
this.items = <itemsModel[]>items;
if (isFirst)
this.dtTrigger.next();
else
this.rerender();
}
文档中的重新渲染
rerender(): void {
this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
dtInstance.destroy();
this.dtTrigger.next();
});
}
https://l-lin.github.io/angular-datatables/#/advanced/rerender
希望对您有所帮助。
另一个可行的解决方案
只需将您的数据 -table 移到一个单独的组件中
和
将您的新 options/data 作为 Input()
import { AfterViewInit, Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild } from '@angular/core';
import { DataTableDirective } from 'angular-datatables';
import { Subject } from 'rxjs';
@Component({
selector: 'app-datatable',
templateUrl: './datatable.component.html',
styleUrls: ['./datatable.component.scss']
})
export class DatatableComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit {
@ViewChild(DataTableDirective, { static: false }) dt!: DataTableDirective;
@Input() dtOptions: DataTables.Settings = {};
dtTrigger: Subject<any> = new Subject<any>();
constructor() { }
private _initComponent() {
this.dtTrigger.next(this.dtOptions);
}
ngOnInit(): void {
}
ngAfterViewInit(): void {
this._initComponent();
}
ngOnChanges(changes: SimpleChanges): void {
}
ngOnDestroy(): void {
this.dtTrigger.unsubscribe();
}
}
<table #dtA datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger"
class="custom-dt-1 table table-sm table-striped card-table w-full row-border hover">
</table>
我正在使用 Angular-DataTables 6.0(可在此处 https://l-lin.github.io/angular-datatables/#/welcome 找到)并且我 运行 遇到了一个反复出现的问题。添加或删除 table 项目时,记录在排序或搜索时消失或重新出现。这可能是因为 adding/deleting 是从数据表外部发生的吗?
我已经尝试添加“数据table="ng"”来修复许多其他建议,但这并没有改变任何东西。我还尝试添加一个重新渲染功能,但在那种情况下,我 运行 变成 'object unsubscribed' 我无法解决的错误。作为参考,一些类似的问题可以在这里找到:类似的例子包括:(
这是我的代码:
HTML:
<table datatable="ng" [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" class="table table-hover" id="t1">
<thead>
<tr>
<th>
<button id="b5">Asset ID</button>
</th>
<th>
<button id="b5">Employee ID</button>
</th>
<th>
<button id="b5">Asset Type</button>
</th>
<th>View</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let a of assets; let i = index">
<td>{{ a.assetID }}</td>
<td>{{ a.currentUser }}</td>
<td>{{ a.assetType }}</td>
<td><button id="button1" (click)="viewAsset(a)"><i class="fas fa-search"></i></button></td>
<td><button id="b2" class="btn" (click)="scrapAsset(a)" (mouseenter)="buttonHover(i)" (mouseleave)="buttonHoverLeave(i)"><i class="{{buttonIconArray[i].text}}"></i></button></td>
</tr>
</tbody>
</table>
-elsewhere in the code-
<button class="btn" id="b1" (click)="addAsset()">Add New Asset</button>
TS
dtOptions: DataTables.Settings = {};
dtTrigger = new Subject();
addAsset()
{
this.confirmChanges = false;
//Create a new asset:
let a: Asset = {
assetID: this.assetID,
currentUser: this.currentUser,
assetType: this.dropdownMessage,
}
//send a notification to the user that owns the new asset
let notify: Notice = {
emplyID: a.currentUser,
notificationSource: "Asset",
details: "A new " + this.dropdownMessage + " was added to your assets.",
timeStamp: new Date()
}
//Add the asset to the server
this.AssetsService.addAsset(a)
.subscribe(asset => { this.assets.unshift(asset);
//All of the inputs need to be emptied
this.clearFields();
})
}
scrapAsset(a: Asset)
{
console.log("The ID is " , a.assetID)
//this.AssetsService.deleteAsset(this.currentAsset).subscribe()
this.confirmChanges = false;
//This deletes the asset from the back-end.
this.AssetsService.deleteAsset(a).subscribe(() => {
console.log('test')
this.assets = this.assets.filter(t => t !== a);
this.NotificationsService.addNotice(notify).subscribe();
this.clearFields(); });
}
dtActivate()
{
this.dtOptions = {
pagingType: 'full_numbers',
pageLength: 7,
order: (this.assets.assetType),
orderClasses: false,
};
this.AssetsService.getAssetsIT().subscribe((assetsImported) => {
this.assets = assetsImported;
this.parseData();
// Calling the DT trigger to manually render the table
this.dtTrigger.next();
});
}
这只是代码的一部分,所以如果您需要查看更多内容,请询问。感谢您提供的任何帮助!
这可行,但我仍在寻找更好的解决方案
setTimeout(function () {$(function () {$('#ng').DataTable();});}, 10);
你可以删除 ng,下面的代码解决了我的问题
<div class="container-fluid">
<div class="page-title">
<h4>Milk Types</h4>
</div>
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-block">
<a href="" class="btn btn-success" href='' [routerLink]="['/milk/create-milk']">
<i class="ti-zip pdd-right-5"></i>
<span>Add New Milk</span>
</a>
<div class="table-overflow">
<table class="table table-lg table-hover" datatable [dtTrigger]="dtTrigger" [dtOptions]="dtOptions">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Status</th>
<th>Price</th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let drink of data">
<td>
<div class="mrg-top-15">
<b class="text-dark font-size-16">{{ drink.id }}</b>
</div>
</td>
<td>
<div class="mrg-top-15">
<span class="text-info pdd-left-20"><b>{{ drink.name }}</b></span>
</div>
</td>
<td>
<div class="col-md-5">
<div class="toggle-checkbox toggle-success checkbox-inline">
<input type="checkbox" name="isEnabled" id="toggle4" [checked]="drink.isEnabled">
<label for="toggle4"></label>
</div>
</div>
</td>
<td>
<div class="mrg-top-15">
<span class="text-info"><b>KD {{ drink.price }}</b></span>
</div>
</td>
<td>
<div class="mrg-top-10 text-center">
<a href="" class="btn btn-warning">
<i class="ti-comment pdd-right-5"></i>
<span>Edit</span>
</a>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
import { Component, OnInit, Input, OnDestroy , ViewEncapsulation } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';
import { pipe, Subscription } from 'rxjs';
import { MilksItem, MilksDataSource } from './milks-datasource';
import { Subject } from 'rxjs';
@Component ({
templateUrl: 'milk.html'
})
export class MilkComponent implements OnInit {
dtOptions: DataTables.Settings = {};
subscription: Subscription;
data: MilksItem[] = [];
dtTrigger: Subject<MilksItem> = new Subject();
constructor(private db: AngularFireDatabase)
{
}
ngOnInit() {
this.dtOptions = {
pagingType: 'full_numbers'
};
this.subscription = this.db.list<MilksItem>('milkTypes').valueChanges().subscribe(d=>{
console.log('data streaming');
this.data = d;
this.dtTrigger.next();
});
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
this.dtTrigger.unsubscribe();
}
}
同样的问题困扰我很久了。在大量的堆栈溢出和文档之后,我找到了解决我的问题的解决方案。也许它对你也有帮助。
允许销毁数据表
ngOnInit() {
this.dtOptions = {
destroy: true,
...
};
...
}
接收新项目的方法(在编辑、插入、添加...后调用)。
onReceived(items){
let isFirst = this.items.length === 0;
this.items = <itemsModel[]>items;
if (isFirst)
this.dtTrigger.next();
else
this.rerender();
}
文档中的重新渲染
rerender(): void {
this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
dtInstance.destroy();
this.dtTrigger.next();
});
}
https://l-lin.github.io/angular-datatables/#/advanced/rerender
希望对您有所帮助。
另一个可行的解决方案
只需将您的数据 -table 移到一个单独的组件中
和
将您的新 options/data 作为 Input()
import { AfterViewInit, Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild } from '@angular/core';
import { DataTableDirective } from 'angular-datatables';
import { Subject } from 'rxjs';
@Component({
selector: 'app-datatable',
templateUrl: './datatable.component.html',
styleUrls: ['./datatable.component.scss']
})
export class DatatableComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit {
@ViewChild(DataTableDirective, { static: false }) dt!: DataTableDirective;
@Input() dtOptions: DataTables.Settings = {};
dtTrigger: Subject<any> = new Subject<any>();
constructor() { }
private _initComponent() {
this.dtTrigger.next(this.dtOptions);
}
ngOnInit(): void {
}
ngAfterViewInit(): void {
this._initComponent();
}
ngOnChanges(changes: SimpleChanges): void {
}
ngOnDestroy(): void {
this.dtTrigger.unsubscribe();
}
}
<table #dtA datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger"
class="custom-dt-1 table table-sm table-striped card-table w-full row-border hover">
</table>