对嵌套字段进行ngTable过滤

时间:2014-03-20 05:32:08

标签: angularjs ngtable

我在ng-table中有一张发票清单,希望能够过滤嵌套属性。 json看起来像这样;

[
  {
     id: 1,
     date: "20/03/2014",
     no: "1",
     client: {
       fullname: "ABC Catering"
     }
  }
]

我的观点看起来像这样

<table ng-table="tableParams" show-filter="true" class="table">
  <tr class='listing' ng-repeat="invoice in $data">
    <td data-title="'Invoice No.'" sortable="'no'" filter="{'no':'text'}">
      {{invoice.no}}
    </td>
    <td data-title="'Date'" sortable="'date'" filter="{'date':'text'}">
      {{invoice.date}}
    </td>
    <td data-title="'Client'" sortable="'client.fullname'" filter="{'client.fullname':'text'}">
      {{invoice.client.fullname}}
    </td>
    <td>
      <a href="/api#/invoices/{{invoice.id}}">Show</a>
      <a href="/api#/invoices/{{invoice.id}}/edit">Edit</a>
      <a href="" ng-confirm-click="destroy(invoice.id)">Delete</a>
    </td>
  </tr>
</table>

我想让client.fullname的过滤工作。如何过滤嵌套属性?

更新

我找到了一个解决方法,我将嵌套字段放入非嵌套JSON元素中,在上面的示例中,我创建了一个JSON ['client_name']元素并将其分配给rails模型中的client.fullname 。然后过滤器工作,因为它没有嵌套。

仍在寻找一种方法,在没有这项工作的情况下我可以做到。

4 个答案:

答案 0 :(得分:7)

您可以对要在JSON响应中过滤的任何内容使用$filter

HERE是一个如何在嵌套的JSON元素上进行过滤的人为例子。示例代码取自ng-table's usage with filters的一个示例。

应用程序中需要注意的主要部分是

$scope.tableParams = new ngTableParams({
    page: 1,
    count: 10,
    filter: {
      'client': 'Bo' //Sample filter
    }
  }, {
    total: data.length,
    getData: function($defer, params) {

      //Note the usage of built in angular filter
      //which is injected in the app

      var orderedData = 
                params.filter() ?
                     $filter('filter')(data, params.filter()) :
                        data;

      $scope.users = 
          orderedData.slice((params.page() - 1) * params.count(), 
                             params.page() * params.count());

      params.total(orderedData.length);
      $defer.resolve($scope.users);
    }
  });

Plunker按预期工作(如果我的要求正确)。如果那些东西不是你的目标,那就大喊一声。 :)

答案 1 :(得分:2)

偶然发现了这个问题并且对任何解决方案都不满意,所以我的尝试就是这样......它只是在我们进行实际过滤之前覆盖过滤器。

getData: function ($defer, params) {

    var filters = params.filter();
    var newFilters = {};

    for (var key in filters) {
        if (filters.hasOwnProperty(key)) {
            switch(key) {
                case 'client.fullname':
                    angular.extend(newFilters, {
                        client: {
                            fullname: filters[key]
                        }
                    });
                    break;
                default:
                    newFilters[key] = filters[key];
            }
        }
    }



    var filtered = filters ?
       $filter('filter')($scope.data, newFilters) :
       $scope.data;

    filtered = params.sorting() ?
                $filter('orderBy')(filtered, params.orderBy()) :
                filtered;

    params.total(filtered.length);

    $defer.resolve(filtered.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}

如果filter属性中有一个点(并且执行PR?),我们可能会考虑扩展过滤器对象的一些通用方法。会更清洁。

答案 2 :(得分:2)

您可以创建自己的过滤器(ngTable v0.7.1):

filter="{client: 'clienttext'}"

...

<script type="text/ng-template" id="ng-table/filters/clienttext.html">
                <input type="text" name="filter-clienttext" ng-model="params.filter().client.name" class="input-filter form-control"/>
            </script>

答案 3 :(得分:1)

由于先前接受的答案在嵌套参数上不再有效,这是我对嵌套过滤/排序/排序getData()的贡献

$scope.tableParams = new NgTableParams({},
{
    getData: function($defer, params) {

        // organize filter as $filter understand it (graph object)
        var filters = {};
        angular.forEach(params.filter(), function(val,key){
            var filter = filters;
            var parts = key.split('.');
            for (var i=0;i<parts.length;i++){
                if (i!=parts.length-1) {
                    filter[parts[i]] = {};
                    filter = filter[parts[i]];
                }
                else {
                    filter[parts[i]] = val;
                }
            }
        })

        // filter with $filter (don't forget to inject it)
        var filteredDatas =
            params.filter() ?
                $filter('filter')(myDatas, filters) :
                myDatas;

        // ordering
        var sorting = params.sorting();
        var key = sorting ? Object.keys(sorting)[0] : null;
        var orderedDatas = sorting ? $filter('orderBy')(filteredDatas, key, sorting[key] == 'desc') : filteredDatas;

        // get for the wanted subset
        var splitedDatas =
            orderedDatas.slice((params.page() - 1) * params.count(),
                params.page() * params.count());

        params.total(splitedDatas.length);

        // resolve the ngTable promise
        $defer.resolve(splitedDatas);
    }
});