是否可以使用PrimeNG DataTable添加自定义过滤器功能?

时间:2017-03-10 09:00:59

标签: angular primeng

基本上所有信息都在标题中提供。

在我看来,我被绑定到可用的filterMatchModes(contains,in,equals,endsWith,startsWith)。在我的用例中,我的列字段是一个数组,没有单个值。

我指定的列如下所示:

<p-column field="types" [filter]="true" header="{{'AIRPORTS.TYPES' | translate}}">
    <template let-airport="rowData" pTemplate="body">
        <span *ngFor="let type of airport.types; let isLast = last">
            {{('AIRPORTS.' + type) | translate}}{{isLast ? '' : ', '}}
        </span>
    </template>
    <template pTemplate="filter" let-col>
        <p-dropdown [options]="choices"
                    [style]="{'width':'100%'}"
                    (onChange)="airportsDataTable.filter($event.value,col.field,col.filterMatchMode)"
                    styleClass="ui-column-filter">
        </p-dropdown>
    </template>
</p-column>

3 个答案:

答案 0 :(得分:4)

我遇到了类似的问题,我必须使用多个可选的过滤器值(来自 import { IonicStorageModule } from '@ionic/storage'; var storage = this.storage; ionViewDidLoad(){ .... //now replace this.storage with the variable storage .... } )过滤数组列数据,因此过滤器也是一个数组。 我找到了一种方法来扩展可用的filterMatchModes,并提供原始源代码的一些帮助。不幸的是,我无法保证这是一种很好的做法,但是嘿,在我使用的版本(PrimeNG 4.1.2)中它可以工作。

您可能需要根据需要调整和调整过滤器功能,但这是我的解决方案在您的案例中的样子(使用p-multiSelect):

  • 在视图中,将DataTable导出为模板引用变量(p-dropdown
  • 通过#dt - decorator
  • 使其可以在组件中访问
  • 将您自己的过滤器功能直接添加到DataTable的过滤器数组中(@ViewChild

<强> component.ts

ngOnInit()

在您的视图中,您现在可以通过将列的filterMatchMode设置为您之前命名的内容来使用新的过滤器功能:

<强> component.html

@Component({...})
export class DatatableComponent implements OnInit {
    ...
    @ViewChild('dt') dt: DataTable;
    ...
    ngOnInit() {
        this.dt.filterConstraints['inCollection'] = function inCollection(value: any[], filter: any): boolean {
            // value = array of data from the current row
            // filter = value from the filter that will be searched in the value-array

            if (filter === undefined || filter === null) {
                return true;
            }

            if (value === undefined || value === null || value.length === 0) {
                return false;
            }

            for (let i = 0; i < value.length; i++) {
                if (value[i].toLowerCase() === filter.toLowerCase()) {
                    return true;
                }
            }

            return false;
        }
    }
}

我在视图中所做的只是设置了<p-dataTable #dt ...> ... <p-column field="types" filterMatchMode="inCollection" header="{{'AIRPORTS.TYPES' | translate}}"> <template let-airport="rowData" pTemplate="body"> <span *ngFor="let type of airport.types; let isLast = last"> {{('AIRPORTS.' + type) | translate}}{{isLast ? '' : ', '}} </span> </template> <template pTemplate="filter" let-col> <p-dropdown [options]="choices" [style]="{'width':'100%'}" (onChange)="dt.filter($event.value,col.field,col.filterMatchMode)" styleClass="ui-column-filter"> </p-dropdown> </template> </p-column> ... </p-dataTable> ,否则我复制了你的代码。 (我还将模板引用重命名为filterMatchMode,使其更短,更易读) 提示:此栏目中您不需要#dt,因为标准过滤器不会显示您的列何时具有自定义过滤器模板。

正如我所提到的,使用这样的自定义过滤器函数,您可以使用[filter]=true过滤器(过滤器函数中的嵌套循环)实现过滤数组数据,搜索数组中的子字符串或其他任何可以想到。

答案 1 :(得分:1)

作为一个简单的解决方法,您可以直接更改FilterUtils:

import { FilterUtils } from 'primeng/utils';

FilterUtils['filterTest'] = (value, filter) => value <= filter && value >= filter;

this.dt.filter(search, 'field', 'filterTest');

答案 2 :(得分:0)

this GitHub issue 中,我们看到他们删除了 filterConstraints,它可以与之前的 PrimeNG 版本一起使用以扩展过滤器功能。

所以...如果您像我一样使用 PrimeNG 版本 9,您可以改用 FilterUtils

import { FilterUtils } from 'primeng/utils';

/**
* Custom filter to be used with PrimeNG Table
* https://www.primefaces.org/primeng/showcase/#/table
* Once we upgrade to version 11, this can be improved with FilterService:
* https://www.primefaces.org/primeng/showcase/#/filterservice
*/
setupCustomTableFilter() {
    FilterUtils['customContains'] = function customContains(value: any, filter: any): boolean {
        if (filter === undefined || filter === null)
            return true;

        if (value === undefined || value === null || value.length === 0)
            return false;

        let searchStringParts = filter.toLowerCase().split(' ') as string[];

        let columnValue = value.toString().toLowerCase();

        //debugger;
        // Make sure that all string parts are contained\included in the column value...
        var isMatch = searchStringParts.every(p => columnValue.includes(p));

        return isMatch;
    }
}

注意需要从import { FilterUtils } from 'primeng/utils';

导入

为了能够在任何地方使用它,您可以在 app.component.ts 文件中定义上面的代码。

最新版本的 PrimeNG which is 11 as of now 添加了一个 FilterService,这使得实现自定义过滤器变得更加简单。