PrimeNG p-table 延迟加载和多重排序 - 进入循环 - 超出最大调用堆栈大小
PrimeNG p-table Lazy loading and Multi Sort - Goes in Loop - Maximum call stack size exceeded
Stackblitz:https://stackblitz.com/edit/primeng-p-table-multisort
配置:
"@angular/cli": "~7.0.2",
"primeng": "7.0.5",
我有一个通过延迟加载实现的 PrimeNG p-table。需要添加多列排序。
Stackblitz 上面的示例代码link。
<p-table [columns]="cols" [value]="cars1" [lazy]="true" [lazyLoadOnInit]="false" (onLazyLoad)="loadList($event)" sortMode="multiple" [multiSortMeta]="multiSortMeta">
如果它是单一排序模式,这可以正常工作。
出现错误 ERROR RangeError: Maximum call stack size exceeded
。
它应该是一个简单的实现,但无法理解这里缺少什么或者 PrimeNG 不支持它。
感谢任何帮助。
这个问题是因为this.cdRef.detectChanges();
原因如下
loadList 绑定到 HTML.
中的 (onLazyLoad)="loadList($event)"
每次发生分页、排序和过滤时,PrimeNg 都会调用该事件。因此,当我们加载和添加排序事件时,它会一直调用。 Angular 每次都会调用更改检测,这会导致错误 ERROR RangeError: Maximum call stack size exceeded
loadList($event: any = {}) {
this.cars1 = [
{
vin: "a1653d4d",
brand: "VW",
year: 1998,
color: "White",
price: 10000
},
{
vin: "ddeb9b10",
brand: "Mercedes",
year: 1985,
color: "Green",
price: 25000
}
];
this.cdRef.detectChanges(); // this is the issue
}
已修改
ngOnInit() {
this.cols = [
{ field: "vin", header: "Vin" },
{ field: "year", header: "Year" },
{ field: "brand", header: "Brand" },
{ field: "color", header: "Color" }
];
this.multiSortMeta = [
{ field: "year", order: 1 },
{ field: "brand", order: -1 }
];
this.loadList();
}
loadList($event: any = {}) {
this.cars1 = [
{
vin: "a1653d4d",
brand: "VW",
year: 1998,
color: "White",
price: 10000
},
{
vin: "ddeb9b10",
brand: "Mercedes",
year: 1985,
color: "Green",
price: 25000
}
];
// this.cdRef.detectChanges();
}
底线是 this.cdRef.detectChanges();
如果您正在使用它,请在应用程序的任何地方小心谨慎地使用它。
已更新 Stackblitz:https://stackblitz.com/edit/primeng-p-table-multisort
它通过原型链覆盖 PrimeNG Table
- sortMultiple
方法。
旧代码:
Table.prototype.sortMultiple = function () {
var _this = this;
if (this.multiSortMeta) {
if (this.lazy) {
this.onLazyLoad.emit(this.createLazyLoadMetadata());
}
else if (this.value) {
if (this.customSort) {
this.sortFunction.emit({
data: this.value,
mode: this.sortMode,
multiSortMeta: this.multiSortMeta
});
}
else {
this.value.sort(function (data1, data2) {
return _this.multisortField(data1, data2, _this.multiSortMeta, 0);
});
}
if (this.hasFilter()) {
this._filter();
}
}
this.onSort.emit({
multisortmeta: this.multiSortMeta
});
this.tableService.onSort(this.multiSortMeta);
}
};
新代码:
Table.prototype.sortMultiple = function () {
const _this = this;
if (this.multiSortMeta) {
if (this.lazy) {
// additional conditions added
if (this.lazyLoadOnInit || (!this.lazyLoadOnInit && this.initialized)) {
this.onLazyLoad.emit(this.createLazyLoadMetadata());
}
} else if (this.value) {
if (this.customSort) {
this.sortFunction.emit({
data: this.value,
mode: this.sortMode,
multiSortMeta: this.multiSortMeta
});
} else {
this.value.sort(function (data1, data2) {
return _this.multisortField(data1, data2, _this.multiSortMeta, 0);
});
}
if (this.hasFilter()) {
this._filter();
}
}
this.onSort.emit({
multisortmeta: this.multiSortMeta
});
this.tableService.onSort(this.multiSortMeta);
}
};
Stackblitz:https://stackblitz.com/edit/primeng-p-table-multisort
配置:
"@angular/cli": "~7.0.2",
"primeng": "7.0.5",
我有一个通过延迟加载实现的 PrimeNG p-table。需要添加多列排序。
Stackblitz 上面的示例代码link。
<p-table [columns]="cols" [value]="cars1" [lazy]="true" [lazyLoadOnInit]="false" (onLazyLoad)="loadList($event)" sortMode="multiple" [multiSortMeta]="multiSortMeta">
如果它是单一排序模式,这可以正常工作。
出现错误 ERROR RangeError: Maximum call stack size exceeded
。
它应该是一个简单的实现,但无法理解这里缺少什么或者 PrimeNG 不支持它。
感谢任何帮助。
这个问题是因为this.cdRef.detectChanges();
原因如下
loadList 绑定到 HTML.
(onLazyLoad)="loadList($event)"
每次发生分页、排序和过滤时,PrimeNg 都会调用该事件。因此,当我们加载和添加排序事件时,它会一直调用。 Angular 每次都会调用更改检测,这会导致错误 ERROR RangeError: Maximum call stack size exceeded
loadList($event: any = {}) {
this.cars1 = [
{
vin: "a1653d4d",
brand: "VW",
year: 1998,
color: "White",
price: 10000
},
{
vin: "ddeb9b10",
brand: "Mercedes",
year: 1985,
color: "Green",
price: 25000
}
];
this.cdRef.detectChanges(); // this is the issue
}
已修改
ngOnInit() {
this.cols = [
{ field: "vin", header: "Vin" },
{ field: "year", header: "Year" },
{ field: "brand", header: "Brand" },
{ field: "color", header: "Color" }
];
this.multiSortMeta = [
{ field: "year", order: 1 },
{ field: "brand", order: -1 }
];
this.loadList();
}
loadList($event: any = {}) {
this.cars1 = [
{
vin: "a1653d4d",
brand: "VW",
year: 1998,
color: "White",
price: 10000
},
{
vin: "ddeb9b10",
brand: "Mercedes",
year: 1985,
color: "Green",
price: 25000
}
];
// this.cdRef.detectChanges();
}
底线是 this.cdRef.detectChanges();
如果您正在使用它,请在应用程序的任何地方小心谨慎地使用它。
已更新 Stackblitz:https://stackblitz.com/edit/primeng-p-table-multisort
它通过原型链覆盖 PrimeNG Table
- sortMultiple
方法。
旧代码:
Table.prototype.sortMultiple = function () {
var _this = this;
if (this.multiSortMeta) {
if (this.lazy) {
this.onLazyLoad.emit(this.createLazyLoadMetadata());
}
else if (this.value) {
if (this.customSort) {
this.sortFunction.emit({
data: this.value,
mode: this.sortMode,
multiSortMeta: this.multiSortMeta
});
}
else {
this.value.sort(function (data1, data2) {
return _this.multisortField(data1, data2, _this.multiSortMeta, 0);
});
}
if (this.hasFilter()) {
this._filter();
}
}
this.onSort.emit({
multisortmeta: this.multiSortMeta
});
this.tableService.onSort(this.multiSortMeta);
}
};
新代码:
Table.prototype.sortMultiple = function () {
const _this = this;
if (this.multiSortMeta) {
if (this.lazy) {
// additional conditions added
if (this.lazyLoadOnInit || (!this.lazyLoadOnInit && this.initialized)) {
this.onLazyLoad.emit(this.createLazyLoadMetadata());
}
} else if (this.value) {
if (this.customSort) {
this.sortFunction.emit({
data: this.value,
mode: this.sortMode,
multiSortMeta: this.multiSortMeta
});
} else {
this.value.sort(function (data1, data2) {
return _this.multisortField(data1, data2, _this.multiSortMeta, 0);
});
}
if (this.hasFilter()) {
this._filter();
}
}
this.onSort.emit({
multisortmeta: this.multiSortMeta
});
this.tableService.onSort(this.multiSortMeta);
}
};