【问题标题】:Is it possible to add custom filterfunction with PrimeNG DataTable?是否可以使用 PrimeNG DataTable 添加自定义过滤功能?
【发布时间】:2017-07-31 13:16:31
【问题描述】:

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

在我看来,我被绑定到可用的 filterMatchModes(包含、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>

【问题讨论】:

  • 你找到解决办法了吗?
  • 不,只有一种解决方法,我将数组转换为逗号分隔的字符串,并使用包含过滤器...似乎没有内置的方式来使用过滤器功能。在源代码中,他们编写现有过滤器函数的位置非常简单,因此只需添加一个就很容易,但是是的..我想也不建议弄乱源代码:)。我应该为功能请求腾出时间,但我又没有多少空闲时间。
  • @Tim 也许我的回答会有所帮助。 (我提到你是因为你不会收到别人问题的答案的通知)
  • 谢谢@mtx - 我会试试你的解决方案。同时,我将数据数组更改为扁平化。

标签: angular filter html-table datatable primeng


【解决方案1】:

我遇到了类似的问题,我必须使用多个可选过滤器值过滤数组列数据(来自p-multiSelect,所以过滤器也是一个数组)。 在原始源代码的帮助下,我找到了一种扩展可用 filterMatchModes 的方法。不幸的是,我不能保证这是一种好的做法,但是,嘿,在我使用的版本(PrimeNG 4.1.2)中它可以工作。

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

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

component.ts

@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;
        }
    }
}

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

component.html

<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,因为当您的列具有自定义过滤器模板时,标准过滤器不会显示。

正如我所提到的,使用这样的自定义过滤器函数,您可以例如使用 p-multiSelect 过滤器(过滤器函数中的嵌套循环)实现过滤数组数据,搜索数组中的子字符串或您能想到的任何其他内容.

【讨论】:

    【解决方案2】:

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

    import { FilterUtils } from 'primeng/utils';
    
    FilterUtils['filterTest'] = (value, filter) => value <= filter && value >= filter;
    
    this.dt.filter(search, 'field', 'filterTest');
    

    【讨论】:

      【解决方案3】:

      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,这使得实现自定义过滤器更加简单。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-02
        • 2021-08-13
        • 2022-09-25
        • 1970-01-01
        • 1970-01-01
        • 2019-11-10
        • 2013-05-04
        • 1970-01-01
        相关资源
        最近更新 更多