Primeng FilterUtils 每个组件是否唯一?
Primeng FilterUtils unique per component?
我有一个页面:
<app-new-grid [isTotals]="false"></app-new-grid>
<hr>
<app-new-grid [isTotals]="true"></app-new-grid>
它呈现良好(通过检查 isTotals 变量有差异),并且是一个 primeng table。
<p-table #dt [value]="data" [columns]="cols" dataKey="name"
[autoLayout]="true" sortMode="single" (sortFunction)="customSort($event)" [customSort]="true" (onFilter)="onFilter($event)">
...
每个网格都有自己的数据集并正确显示。但是,当我尝试过滤第一个 table 时,它使用的是为第二个 table 设置的变量。这是因为 table 声明中的 #dt 吗?我该如何解决?
组件:
import { Component, OnInit, Input } from '@angular/core';
import { } from '@angular/cdk/scrolling';
import { MyData } from './MyData-Interface';
import rawJson from '../../../assets/json/myData.json';
import { SelectItem } from 'primeng/api/selectitem';
import { FilterUtils } from 'primeng/utils';
import { SortEvent } from 'primeng/api/sortevent';
import { PercentPipe } from '@angular/common'
@Component({
selector: 'app-new-grid',
templateUrl: 'new-grid.component.html',
styleUrls: ['new-grid.component.scss']
})
export class MyDataNewGridComponent implements OnInit {
@Input() isTotals: boolean;
myData: MyData[];
pp: PercentPipe;
cols: any[];
classSelect: any[] = [];
classes: SelectItem[];
products: SelectItem[];
soldRangeValues: number[];
soldRangeMin: number;
soldRangeMax: number;
rowGroupMetadata = {};
groupingVar = 'name';
constructor() { }
ngOnInit(): void {
console.log(this.isTotals);
this.pp = new PercentPipe('en-US');
this.myData = <MyData[]>rawJson.filter(
detail => !this.isTotals ? detail.sortOrder < 5000 : detail.sortOrder > 5000);
this.fillMyData();
this.cols = [
{ field: 'name', header: 'Product' },
{ field: 'description', header: 'Class' }
];
var productNames = this.myData
.map(item => item.name)
.filter((value, index, self) => self.indexOf(value) === index);
this.products = productNames.map(item => ({ label: item, value: item }));
this.initializeRangeValues();
this.declareFilters();
this.updateRowGroupMetaData(this.myData);
}
private fillMyData() {
//Group by defined variable
var grouped = this.myData.reduce((g: any, person: MyData) => {
g[person[this.groupingVar]] = g[person[this.groupingVar]] || [];
g[person[this.groupingVar]].push(person);
return g;
}, {});
this.myData = [];
for (let key of Object.keys(grouped)) {
let entry = grouped[key] as MyData[];
//Check if we already have a subtotal
var temp = entry.map(item => item['description']).filter(x => x.toUpperCase().includes("TOTAL"));
if (temp.length === 0) {
var subTotal = {} as MyData;
subTotal.name = entry[0].name;
entry.push(subTotal);
}
for (let x of entry) {
this.myData.push(x);
}
}
}
declareFilters() {
FilterUtils['soldRangeFilter'] = (value, filter): boolean => {
return value >= this.soldRangeValues[0] && value <= this.soldRangeValues[1];
}
}
initializeRangeValues() {
let sold = this.getMinMax('sold');
this.soldRangeMin = sold[0];
this.soldRangeMax = sold[1];
this.soldRangeValues = [this.soldRangeMin, this.soldRangeMax];
}
onFilter(event) {
this.updateRowGroupMetaData(event.filteredValue);
}
updateRowGroupMetaData(data) {
this.rowGroupMetadata = {};
if (data) {
for (let i = 0; i < data.length; i++) {
let rowData = data[i];
let name = rowData.name;
if (i == 0) {
this.rowGroupMetadata[name] = { index: 0, size: 1 };
}
else {
let previousRowData = data[i - 1];
let previousRowGroup = previousRowData.name;
if (name === previousRowGroup)
this.rowGroupMetadata[name].size++;
else
this.rowGroupMetadata[name] = { index: i, size: 1 };
};
}
}
}
arraySum = function (items, prop) {
return items.reduce(function (a, b) {
return a + b[prop];
}, 0);
};
customSort(event: SortEvent) {
let map = new Map<string, number>(event.data
.filter(x => x.description.includes('Subtotal'))
.map(x => [x[this.groupingVar], x[event.field]]));
this.myData = event.data.slice()
.sort((a, b) => (map.get(a.name) - map.get(b.name)) * event.order);
this.updateRowGroupMetaData(this.myData);
}
getMinMax(field: string) {
let fieldSelect = this.myData.map(item => item[field]).filter(item => Number.isFinite(item));
fieldSelect = fieldSelect.sort((n1, n2) => n1 - n2);
return [fieldSelect[0], fieldSelect[fieldSelect.length - 1]];
}
}
更新:
所以我发现问题出在我对 FilterUtils 的使用上。如果我将每个网格的过滤器声明更改为唯一:
declareFilters() {
FilterUtils['soldRangeFilter' + isTotals] = (value, filter): boolean => {
return value >= this.soldRangeValues[0] && value <= this.soldRangeValues[1];
}
}
然后就可以了。是否有更简洁的方法来确保每个网格都有自己的 FilterUtils 实例?
所以我发现问题出在我对 FilterUtils 的使用上。如果我将每个网格的过滤器声明更改为唯一:
declareFilters() {
FilterUtils['soldRangeFilter' + isTotals] = (value, filter): boolean => {
return value >= this.soldRangeValues[0] && value <= this.soldRangeValues[1];
}
}
然后就可以了。
更高版本的 primeng 将 FilterUtils 更改为服务。
我有一个页面:
<app-new-grid [isTotals]="false"></app-new-grid>
<hr>
<app-new-grid [isTotals]="true"></app-new-grid>
它呈现良好(通过检查 isTotals 变量有差异),并且是一个 primeng table。
<p-table #dt [value]="data" [columns]="cols" dataKey="name"
[autoLayout]="true" sortMode="single" (sortFunction)="customSort($event)" [customSort]="true" (onFilter)="onFilter($event)">
...
每个网格都有自己的数据集并正确显示。但是,当我尝试过滤第一个 table 时,它使用的是为第二个 table 设置的变量。这是因为 table 声明中的 #dt 吗?我该如何解决?
组件:
import { Component, OnInit, Input } from '@angular/core';
import { } from '@angular/cdk/scrolling';
import { MyData } from './MyData-Interface';
import rawJson from '../../../assets/json/myData.json';
import { SelectItem } from 'primeng/api/selectitem';
import { FilterUtils } from 'primeng/utils';
import { SortEvent } from 'primeng/api/sortevent';
import { PercentPipe } from '@angular/common'
@Component({
selector: 'app-new-grid',
templateUrl: 'new-grid.component.html',
styleUrls: ['new-grid.component.scss']
})
export class MyDataNewGridComponent implements OnInit {
@Input() isTotals: boolean;
myData: MyData[];
pp: PercentPipe;
cols: any[];
classSelect: any[] = [];
classes: SelectItem[];
products: SelectItem[];
soldRangeValues: number[];
soldRangeMin: number;
soldRangeMax: number;
rowGroupMetadata = {};
groupingVar = 'name';
constructor() { }
ngOnInit(): void {
console.log(this.isTotals);
this.pp = new PercentPipe('en-US');
this.myData = <MyData[]>rawJson.filter(
detail => !this.isTotals ? detail.sortOrder < 5000 : detail.sortOrder > 5000);
this.fillMyData();
this.cols = [
{ field: 'name', header: 'Product' },
{ field: 'description', header: 'Class' }
];
var productNames = this.myData
.map(item => item.name)
.filter((value, index, self) => self.indexOf(value) === index);
this.products = productNames.map(item => ({ label: item, value: item }));
this.initializeRangeValues();
this.declareFilters();
this.updateRowGroupMetaData(this.myData);
}
private fillMyData() {
//Group by defined variable
var grouped = this.myData.reduce((g: any, person: MyData) => {
g[person[this.groupingVar]] = g[person[this.groupingVar]] || [];
g[person[this.groupingVar]].push(person);
return g;
}, {});
this.myData = [];
for (let key of Object.keys(grouped)) {
let entry = grouped[key] as MyData[];
//Check if we already have a subtotal
var temp = entry.map(item => item['description']).filter(x => x.toUpperCase().includes("TOTAL"));
if (temp.length === 0) {
var subTotal = {} as MyData;
subTotal.name = entry[0].name;
entry.push(subTotal);
}
for (let x of entry) {
this.myData.push(x);
}
}
}
declareFilters() {
FilterUtils['soldRangeFilter'] = (value, filter): boolean => {
return value >= this.soldRangeValues[0] && value <= this.soldRangeValues[1];
}
}
initializeRangeValues() {
let sold = this.getMinMax('sold');
this.soldRangeMin = sold[0];
this.soldRangeMax = sold[1];
this.soldRangeValues = [this.soldRangeMin, this.soldRangeMax];
}
onFilter(event) {
this.updateRowGroupMetaData(event.filteredValue);
}
updateRowGroupMetaData(data) {
this.rowGroupMetadata = {};
if (data) {
for (let i = 0; i < data.length; i++) {
let rowData = data[i];
let name = rowData.name;
if (i == 0) {
this.rowGroupMetadata[name] = { index: 0, size: 1 };
}
else {
let previousRowData = data[i - 1];
let previousRowGroup = previousRowData.name;
if (name === previousRowGroup)
this.rowGroupMetadata[name].size++;
else
this.rowGroupMetadata[name] = { index: i, size: 1 };
};
}
}
}
arraySum = function (items, prop) {
return items.reduce(function (a, b) {
return a + b[prop];
}, 0);
};
customSort(event: SortEvent) {
let map = new Map<string, number>(event.data
.filter(x => x.description.includes('Subtotal'))
.map(x => [x[this.groupingVar], x[event.field]]));
this.myData = event.data.slice()
.sort((a, b) => (map.get(a.name) - map.get(b.name)) * event.order);
this.updateRowGroupMetaData(this.myData);
}
getMinMax(field: string) {
let fieldSelect = this.myData.map(item => item[field]).filter(item => Number.isFinite(item));
fieldSelect = fieldSelect.sort((n1, n2) => n1 - n2);
return [fieldSelect[0], fieldSelect[fieldSelect.length - 1]];
}
}
更新:
所以我发现问题出在我对 FilterUtils 的使用上。如果我将每个网格的过滤器声明更改为唯一:
declareFilters() {
FilterUtils['soldRangeFilter' + isTotals] = (value, filter): boolean => {
return value >= this.soldRangeValues[0] && value <= this.soldRangeValues[1];
}
}
然后就可以了。是否有更简洁的方法来确保每个网格都有自己的 FilterUtils 实例?
所以我发现问题出在我对 FilterUtils 的使用上。如果我将每个网格的过滤器声明更改为唯一:
declareFilters() {
FilterUtils['soldRangeFilter' + isTotals] = (value, filter): boolean => {
return value >= this.soldRangeValues[0] && value <= this.soldRangeValues[1];
}
}
然后就可以了。 更高版本的 primeng 将 FilterUtils 更改为服务。