Custom filter with AngularJS ngTable

泪湿孤枕 提交于 2019-12-02 23:32:34

You don't need the watches nor the custom filters you created. Actually angular's 'filter' filter is quite powerful.

You just need to create an object that keeps track of your filter values with members that match your items fields. Something like this.

$scope.filter = {
    key: undefined,
    failed: undefined
}

then you can take it back inside the getData callback using params.filter(). I have updated your plunker here. You can also check the sample below:

var app = angular.module('main', ['ngTable']);

app.controller('MainCtrl', function($scope, $http, $filter, ngTableParams) {

    $scope.completedQueries = [{"key":"abc000","lastRun":123,"lastSuccessfulTime":9999,"elapsedTime":456,"rows":10,"failed":false},{"key":"abc001","lastRun":1234,"lastSuccessfulTime":9999,"elapsedTime":456,"rows":10,"failed":false},{"key":"abc002","lastRun":111111111,"lastSuccessfulTime":9999,"elapsedTime":456,"rows":10,"failed":true},{"key":"abc003","lastRun":123,"lastSuccessfulTime":9999,"elapsedTime":456,"rows":10,"failed":false},{"key":"abc004","lastRun":1234,"lastSuccessfulTime":9999,"elapsedTime":456,"rows":10,"failed":true},{"key":"abc005","lastRun":111111111,"lastSuccessfulTime":9999,"elapsedTime":456,"rows":10,"failed":false},{"key":"abc006","lastRun":123,"lastSuccessfulTime":9999,"elapsedTime":456,"rows":10,"failed":false},{"key":"abc007","lastRun":1234,"lastSuccessfulTime":9999,"elapsedTime":456,"rows":10,"failed":false},{"key":"abc008","lastRun":111111111,"lastSuccessfulTime":9999,"elapsedTime":456,"rows":10,"failed":false},{"key":"abc009","lastRun":123,"lastSuccessfulTime":9999,"elapsedTime":456,"rows":10,"failed":false},{"key":"abc010","lastRun":1234,"lastSuccessfulTime":9999,"elapsedTime":456,"rows":10,"failed":false},{"key":"abc011","lastRun":111111111,"lastSuccessfulTime":9999,"elapsedTime":456,"rows":10,"failed":false},{"key":"abc012","lastRun":123,"lastSuccessfulTime":9999,"elapsedTime":456,"rows":10,"failed":true},{"key":"abc013","lastRun":1234,"lastSuccessfulTime":9999,"elapsedTime":456,"rows":10,"failed":false},{"key":"abc014","lastRun":111111111,"lastSuccessfulTime":9999,"elapsedTime":456,"rows":10,"failed":false},{"key":"abc015","lastRun":123,"lastSuccessfulTime":9999,"elapsedTime":456,"rows":10,"failed":true},{"key":"abc016","lastRun":1234,"lastSuccessfulTime":9999,"elapsedTime":456,"rows":10,"failed":false},{"key":"abc017","lastRun":111111111,"lastSuccessfulTime":9999,"elapsedTime":456,"rows":10,"failed":false}];
    $scope.filter = {
        key: undefined,
        failed: undefined
    };
    $scope.tableParams =  new ngTableParams({
        page: 1,
        count: 10,
        filter: $scope.filter
    }, {
        debugMode: true,
        total: $scope.completedQueries.length,
        getData: function($defer, params) {
            var orderedData = params.sorting() ? $filter('orderBy')($scope.completedQueries, params.orderBy()) : data;
            orderedData	= $filter('filter')(orderedData, params.filter());
            params.total(orderedData.length);
            $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
        }
    });
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/ng-table/0.3.3/ng-table.min.css" rel="stylesheet"/>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ng-table/0.3.3/ng-table.min.js"></script>
<div  ng-app="main"  ng-controller="MainCtrl">
  <label for="keysFilter">Filter Keys:</label>
  <input id="keysFilter" type="text" ng-model="filter.key"/>
  <label for="showOnlyFailed">Show only queries that failed?</label>
  <input id="showOnlyFailed" type="checkbox" ng-model="filter.failed"/>
  <br/>
  <table ng-table="tableParams" class="table">
    <tr ng-repeat="queryInfo in $data">
        <td data-title="'Key'" sortable="'key'">{{queryInfo.key}}</td>
        <td data-title="'Last Run'" sortable="'lastRun'">{{queryInfo.lastRun}}</td>
        <td data-title="'Last Successful Run'" sortable="'lastSuccessfulRun'">{{queryInfo.lastSuccessfulRun}}</td>
        <td data-title="'Elapsed Time'" sortable="'elapsedTime'">{{queryInfo.elapsedTime}} ms</td>
        <td data-title="'Rows'" sortable="'rows'">{{queryInfo.rows}}</td>
        <td data-title="'Failed'" sortable="'failed'">{{queryInfo.failed}}</td>
        <td data-title="''"><button class="btn">Detail</button></td>
    </tr>
  </table> 
<div>

It looks like you're experiencing an issue with ng-table itself, which is a 3rd party library that's not really well supported.

As evidence of this, check out their Github page, which has over 200 open issues and 1,200 stars (1:6):

https://github.com/esvit/ng-table

Compare this to a library like D3.js, which enjoys the full technical and financial support of the New York Times. It has 150 issues and over 30,000 stars (1:200).

https://github.com/mbostock/d3

Large number of open issues means people are finding bugs faster than the developers can solve them. More than likely, the developers have probably moved on to new projects and are no longer interested in maintaining this library.

In other words, you've run into a functionality limitation of the library itself. When this happens, you have two options,

1. Stop using the library and select a new library, or build your own.

Sadly I have looked into this and there is not a really good angular table library right now

2. Fork the repository, learn the inner workings of the library, implement the feature you want yourself, and make a pull request.

Just so this is not a total bummer, maybe UI-Grid can help you where ng-table has failed.

http://ui-grid.info/

Disclosure: I am not affiliated with ui-grid and am still pretty much on the fence over whether it is even good

In our situation we have used ng-table-dynamic for us to have a set of custom columns those custom columns needs to be map on list of users from the database at code level. Since mapping is manually happening in the code level we find a unique way of handling filtering and sorting with ng-table-dynamic.

Here is the code


          function initialize() {
    this.$scope.userList = new this.NgTableParams({
          page: 1,
          count: 10
        }, {
          counts: [],
          total: this.usersList.length,
          getData: (params) => { // handles custom sorting or filtering
            var results= [];


            //add logic here if any
            results = this.$filter('filter')(results, this.$scope.searchKey);

            params.total(results.length);
            pages = Math.ceil(params.total()/ params.count());
            if(pages > 1){
              results = results.slice((params.page() - 1)* params.count(), params.page() * params.count());
            }
            return results;
          }
        });
    }

Note: We used an declared variable results, where it will contain the data to be rendered to the table.

Also in controller we need to handle the custom search

here is the code:


    this.$scope.$watch('searchKey',(newValue)=>{
          if(typeof newValue !== 'undefined'){
            this.$scope.userList.reload();// cause re-render of result in key-press
          }
    });

This code will trigger getData function of NgTableParams, allowing you to build your custom filter.

Note: You need to also preserve the result array so you need to store in in $scope variable

Code will look like this


    function foo() {
        Provider('Method', (error, users) => {
          if (!error) {
            this.usersList  = users;
            this.$scope.userList.reload(); // cause render of results to the table
            this.$scope.$apply();
          }
        });
      }

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!