5

我在 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

4 回答 4

7

你可以使用$filter任何你想从 JSON 响应中过滤的东西。

HERE是一个人为的例子,说明如何对嵌套的 JSON 元素进行过滤。示例代码取自ng-table 与 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 按预期工作(如果我的要求正确)。如果那不是您的目标,请大声喊叫。:)

于 2014-04-08T03:19:33.560 回答
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()));
}

如果过滤器属性中有一个点(并做一个 PR ?),我们可能会考虑一些扩展过滤器对象的通用方法。会干净很多。

于 2015-04-29T13:59:02.900 回答
2

由于先前接受的答案不再适用于嵌套参数,这是我对嵌套过滤/可排序/排序 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);
    }
});
于 2016-02-11T11:11:45.640 回答
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>
于 2015-12-17T16:08:12.393 回答