AngularJS ng-grid筛选器--筛选文本格式

25

我正在使用AngularJS ng-grid (v2.0.7 v2.0.8),我希望了解API中filterText字段的语法。

特别是,我想知道如何在特定列或多个列上进行筛选,并过滤一个或多个条目。

有很多带有ng-grid和filter标签的stackoverflow问题,虽然它们很有用,但目前还没有一个完整概述filterText格式的问题。

2个回答

92
在撰写本文时,没有关于如何一般构建“filterText”字符串的摘要。经过研究ng-grid.js代码并进行一些猜测,我发现“filterText”比当前文档所示的更加强大和表达力强。

示例设置

为了设置答案,请首先考虑一个包含以下定义的网格,位于某个控制器中:

  $scope.pricing_data = data['records'];

  $scope.gridOptions = { 
    data: 'pricing_data',
    columnDefs: [
      { field: 'ticker', displayName: 'Ticker' },
      { field: 'date',   displayName: 'Date'   },
      { field: 'close',  displayName: 'Close'  },
      { field: 'volume', displayName: 'Volume' }
    ],
    filterOptions: {filterText: '', useExternalFilter: false},
    showFilter: true
  };

data['records']中的对象可以是从后端发送过来的JSON对象。一个示例表格可能如下所示:

an unfiltered table

目前,filterText为空,因此显示所有记录。
在网格的右上方,向下的箭头可见,因为showFilter为true。单击向下箭头会显示一个输入框,该输入框绑定到变量'filterText'。对于本讨论,我将使用此下拉列表显示一些结果,但通常您可以直接在控制器代码中分配给filterText。下拉列表如下所示:

showFilter widget bound to filterText

在表格中搜索所有字段

默认情况下,filterText会对表格中的每个单元格执行正则表达式。输入字符'a'会选择所有记录,其中任何一个条目(或列)中都有字符'a'。输入'ab'会选择所有记录,其中任何一个条目中都包含字符序列'ab'。根据您的要求,此行为可能完全适合。然而,在大数据集的情况下,通常希望仅针对列进行过滤,而不是整个网格,因为数据的性质(例如选择价格标记)以及搜索整个网格的高成本。

按列搜索

为了在只有一列上搜索字符串或正则表达式,filterText的语法如下:

filterText = '<displayName>:<literal>'

例如,

first column filter

这里的displayName是'Date'(不使用字段值,必须使用displayName),后面跟着一个冒号':'和部分字符串。结果是只选择了三条记录,这些记录与10月30日相关联。

让我们扩展搜索范围。要搜索10月30日或者10月31日,语法如下:

filterText = '<displayName>:<literal 1>|<literal 2>|...'

其中一个管道符“|”分隔每个字符串部分。您可以将它们连接在一起,无论需要多少个。一个多日期过滤器可能如下所示:

enter image description here

显然,选择是以“或”为基础的。我的例子不太好,因为股票代码和日期具有不同的字符。所以你可以相信我只搜索了日期列,或者设置自己的例子。(或者更好的方法是阅读ng-grid中的buildSearchConditions()函数,它在这方面非常清晰明了)。

在多个列中搜索条目

在多个列中搜索只需要语法上对搜索单一列的扩展。这个语法是:

filterText = '<displayName 1>:<lit 1>[|<lit 2>|..];<displayName 2>:<lit a>[|<lit b>|..][;..]'

操作性的词法元素是分号 ';',用于分隔每个列名称。

继续上面的示例,让我们搜索10月30日或10月31日的 nyt 或 nvda。它看起来像:

multicolumn filter 1

逻辑上,该过滤器搜索 (在 Ticker 中寻找 nyt 或者 nvda) 并且 (在 Date 中寻找 10-30 或者 10-31)。

网格更新

我对来自单元格编辑的更新不太熟悉。我想结果是一样的。

当 angular-js 控制器与后端协同工作更新网格数据时,那么更新的数据会被推送 通过 过滤器。这是一个美妙的结果,实际上过滤器持久存在。

已知缺陷 -- 清除

目前已经有一个解决已知问题的修复程序,其中清除filterText几乎或确实会使浏览器挂起。我关注的报告是这个:ng-grid issue 777。在ng-grid issue 848之后合并了修复程序。当应用于大型数据集的过滤器被清除时,我可以明确确认我看到了性能不佳。我还没有测试修复程序。
更新:
我刚刚安装了ng-grid 2.0.8。清除问题已经修复。效果很好。

ng-grid 3.0

ng-grid 3.0目前正在筹划中。ng-grid 2.0已经包含了很多优秀的功能,但像任何新代码一样,需要进行一些重写来改进。我鼓励ng-grid开发人员保留他们已经包含的过滤器功能,并可能扩展性能或范围。


6
非常好的回答,但我希望它可以被添加到ngGrid Wiki中。回答了一个难题,我的用户需要搜索包含冒号“:”字符的字符串,这恰巧在我的网格数据集中很普遍。通过修改用户的搜索字符串,将“:”和“;”替换为转义等价物,例如:`filterOptions.filterText = srchTxt.replace(/:/g, "\\x3a").replace(/;/g, "\\x3b");`我能够解决这个问题。 - willw
非常感谢。有一个注意点 - 对我来说,这也适用于使用字段名称而不是displayName。不确定为什么,可能是ng-grid已经得到了改进。 - JustAMartin
@Martin 你好 Martin,你使用的是哪个版本?ng-grid确实在不断地进步。此外,你的字段名称和显示名称实际上是相同的吗?否则,至少对于v2.0.8来说,这让我有点惊讶。但话说回来,这些天我很少感到惊讶了。 - JayInNyc
@JayInNyc 我的列定义是 {field:'name', displayName:'Firmas nosaukums'},{field:'registration_number', 'Reģistrācijas numurs'},当我将 filterText 设置为 name:a;registration_number:11; 时,它可以正确地通过这两个条件过滤数据。我使用的是 ng-grid-2.0.14 版本。 - JustAMartin
@Martin -- 好的,太棒了。看起来是代码更改。感谢您的添加。 - JayInNyc
显示剩余3条评论

9

根据JayInNyc的回答,我做了一些事情,使用户更容易使用,而不是遵循那个语法。我基本上监视任何我想要过滤的字段。在这种情况下,我有一个输入字段用于姓名和城市。

$scope.filterOptions = {
    filterText: ''
};
$scope.filterName = '';
$scope.filterCity = '';

$scope.$watch('filterName', function (value) {

    setFilterText();
});

$scope.$watch('filterCity', function (value) {

    setFilterText();
});

function setFilterText()
{
    $scope.filterOptions.filterText = 'Name: ' + $scope.filterName + ';City:' + $scope.filterCity;
}

顺便说一句 - 我想使用编译函数,但好像不起作用。我尝试了以下代码,但它没有起作用。

filterOptions.filterText = $compile('Name:{{filterName}};Category:{{filterCategory}}')(scope);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接