-->

Server-side filtering with ng-grid: binding issue?

2019-07-05 12:45发布

问题:

I'm posting this with reference to this previous post Server-side paging+filtering+sorting for ng-grid with WebAPI, hoping to be able to finally come up with a simple, yet working sample of using ng-grid with external data sources. Up to this point, I've managed to implement external paging and sorting, but I'm facing an issue with filtering.

It seems like the filterText property of ng-grid filter options is not bound to the view. When I type something in the filter's text of the ng-grid my $watch-ed function does not get called, and thus I have no chance to request filtered data to the server. Yet, the same watch expressions work fine when used e.g. for paging or sorting.

By digging around a bit, I found this post https://github.com/angular-ui/ng-grid/pull/456 about a bug right in this area, but it's not clear if this is still an open issue. Could anyone help? Here is the relevant JS code snippet:

var app = angular.module('MyApp', ['ngGrid']);
app.controller('MainController', ['$scope', '$http', function ($scope, $http) {
    $scope.items = [];
    $scope.filterOptions = {
        filterText: "",
        useExternalFilter: true
    };
    $scope.totalServerItems = 0;
    $scope.pagingOptions = {
        pageSizes: [25, 50, 100],
        pageSize: 25,
        currentPage: 1
    };
    $scope.sortOptions = {
        // omitted for brevity...
    };

    $scope.gridOptions = {
        data: "items",
        columnDefs: [
            { field: "id", displayName: "ID", width: "60" },
            { field: "name", displayName: "Name", pinnable: true },
            { field: "age", displayName: "Age", width: "60" },
            { field: "isFemale", displayName: "F", width: "40" }
        ],
        enablePaging: true,
        enablePinning: true,
        pagingOptions: $scope.pagingOptions,        
        filterOptions: $scope.filterOptions,
        keepLastSelected: true,
        multiSelect: false,
        showColumnMenu: true,
        showFilter: true,
        showGroupPanel: true,
        showFooter: true,
        sortInfo: $scope.sortOptions,
        totalServerItems: "totalServerItems",
        useExternalSorting: true,
        i18n: "en"
    };

    $scope.refresh = function() {
        setTimeout(function () {
            // call the server and get data into $scope.items...
        }, 100);
    };

    // this WORKS    
    $scope.$watch('pagingOptions', function (newVal, oldVal) {
        if (newVal !== oldVal) {
            $scope.refresh();
        }
    }, true);

    // this DOES NOT WORK: the function never gets called
    $scope.$watch('filterOptions', function (newVal, oldVal) {
        if (newVal !== oldVal) {
            $scope.refresh();
        }
    }, true);

    // this WORKS
    $scope.$watch('sortOptions', function (newVal, oldVal) {
        if (newVal !== oldVal) {
            $scope.refresh();
        }
    }, true);

    $scope.refresh();
}]);

回答1:

This might be bit late but its better late than never :)

I had success by directly binding to the filterText property of gridOptions like below

$scope.$watch('gridOptions.$gridScope.filterText', function (newVal, oldVal) {
        if (newVal !== oldVal) {
        }
}, true);