【问题标题】:ng-repeat filter with filtered properties具有过滤属性的 ng-repeat 过滤器
【发布时间】:2014-05-30 11:07:26
【问题描述】:

我有一个数据列表,我想使用 Angular 的典型过滤进行搜索。

我有一个对象数组(以下几个之一):

{
   vendor: 'Joan\'s Produce',
   date: '2014-04-07',
   total: 888.11,
   note: 'insert note',
   description: 'fresh produce',
   terms: 'Net 10',
   deliverer: 'Joe Truck',
   paid: true
}

<thead> 我有输入字段来搜索日期和总计字段。

<th style="vertical-align:text-top; width:250px;">Date<br />
    <div class="input-group input-group-sm">
        <input type="text" class="form-control" ng-model="dateQuery.date" />
        <span class="input-group-addon"><button type="button" class="close" aria-hidden="true" ng-click="dateQuery=''">&times;</button></span>
    </div>
</th>

表中的数据有自己的过滤器:

<tr ng-repeat="inv in invoices | filter:dateQuery | filter:amountQuery">
    <td>{{inv.date | date:'MM/dd/yyyy'}}</td>...
    <td>{{inv.total | currency}}</td>
</tr>

ng-repeat 中的过滤器格式化日期并将总计更改为货币。当我现在搜索这些过滤器时,它似乎只搜索 ng-repeat 从中提取的原始数据。

有没有办法以搜索过滤结果的方式构建输入过滤器?例如,我必须搜索 2014-04-07 的日期,并且无法添加总过滤器中的 $。

I have build a demo here

【问题讨论】:

  • 您需要在控制器中预先过滤原始数据,以便invoices 包含您需要过滤的数据。或者创建一个自定义过滤器,从过滤器键中去除$

标签: angularjs angularjs-ng-repeat angularjs-filter


【解决方案1】:

我最终利用 Underscore.js 在范围对象上运行 foreach 循环

_.each($scope.invoices, function (invoice) {
    invoice.filteredDate = $filter('date')(invoice.date, 'MM/dd/yyyy');
    invoice.filteredTotal = $filter('currency')(invoice.total, '$');
});

然后在我的 HTML 中引用了新字段

<tr ng-repeat="inv in invoices | orderBy:predicate:reverse | filter:dateQuery | filter:totalQuery">
    <td>{{inv.filteredDate}}</td>
    <td>{{inv.vendor}}</td>
    <td>{{inv.filteredTotal}}</td>
    <td>{{inv.terms}}</td>
    <td class="center"><input type="checkbox" ng-model="inv.paid" disabled /></td>
    <td class="center">
        <a ng-click="invoice(inv, $index)"><i class="fa fa-edit"></i></a>
    </td>
</tr>

【讨论】:

    【解决方案2】:

    ng-repeat 上的过滤器只会过滤原始数据,这就是 ng-repeat 的工作原理。要过滤表格数据单元格中过滤器的输出,我可以看到两个选项:

    • 将日期和货币的预过滤值附加到您要过滤的对象。为了使事情保持干燥,您可以为此目的使用过滤器本身,在控制器或其他配件中:

      object.currencyFlat = $filter('currency')(object.total);
      
    • 构建自定义过滤器,根据您在表格中直观呈现的值动态过滤:

      angular.module('myModule').filter('myCurrencyFilter', function($filter) {
          return function(array, text) {
              // Could be more sophisticated
              return array.filter(function(item) {
                  return $filter('currency')(item).indexOf(text) !== -1;
              });
          }
      });
      

    在这两个中,第一个会更快,因为它只将对象的总数格式化为货币一次。

    我认为这两种方法都不是特别漂亮。我希望看到更好的解决方案。

    【讨论】:

    • 您会构建其他东西来循环通过$scope.invoices 来构建“干”数据吗?
    • 是的,您必须将此数据附加到 for 循环或控制器中的某些内容中,以便您的对象同时具有 currency 属性和 $scope.invoices 中的 currencyFlat。您将过滤currencyFlat,但显示currency(如果它们完全一样,您还可以显示预先格式化(过滤)的currencyFlat值)。
    • 您的解决方案是我最终所做的事情的催化剂,请参阅我的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-21
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多