角度ui-grid/ng-grid filter更换频繁

use*_*169 6 angularjs ng-grid angular-ui-grid

我正在尝试使用服务器端排序,服务器端分页和服务器端过滤来实现角度网格.使用ui-grid(不稳定),我添加了ui.grid.paging并使所有内容都运行起来.非常好,对开发人员的称赞.

但是.... $ scope.gridApi.core.on.filterChanged正在为每个按下的键触发,因此当我在givenname列中搜索"Patrick"时,会触发七个事件并且七个get-requests命中我的服务器.更糟糕的是,因为它是一个很大的集合,我正在过滤,这个操作相当昂贵,结果我甚至相互超越,就像最特定的过滤器获得最快的结果,在处理不太具体的结果之前触发成功.

我想放慢速度,比如"进入后停火".我是javascript和REST的新手,这是我的第一个真实世界项目.我真的很感激如何处理这个问题的任何想法.这感觉就像一个常见的场景,因此可能会有一些我缺少的标准解决方案或最佳实践.

你的,帕特里克.

San*_*edo 16

如果你想"全角",我建议$timeouton.filterChanged事件处理程序中使用:

if (angular.isDefined($scope.filterTimeout)) {
    $timeout.cancel($scope.filterTimeout);
}
$scope.filterTimeout = $timeout(function () {
    getPage();
}, 500);
Run Code Online (Sandbox Code Playgroud)

其中500是你想要在每个on.filterChanged事件之前等待到服务器之前的时间(以毫秒为单位),而getPage()是实际进入服务器并检索数据的函数.

不要忘记$timeout在控制器的'destroy'事件中取消你:

$scope.$on("$destroy", function (event) {
    if (angular.isDefined($scope.filterTimeout)) {
        $timeout.cancel($scope.filterTimeout);
    }
});
Run Code Online (Sandbox Code Playgroud)


小智 9

我正在处理同样的问题,我提出了另一个解决方案,恕我直言更加"角度友好".我使用了 Angular 1.3中引入的ngModelOptions指令.我用自定义的模板替换了uiGrid的默认过滤器模板("ui-grid/ui-grid-filter"),并在输入上配置了ngModelOptions指令,默认的去抖值为300 ms,模糊为0 ms.

这是一个基于ui-grid 3.0.5原始模板的示例模板,我还通过Bootstrap类更改了默认的CSS类:

$templateCache.put('ui-grid/ui-grid-filter-custom',
  "<div class=\"ui-grid-filter-container\" ng-repeat=\"colFilter in col.filters\" ng-class=\"{'ui-grid-filter-cancel-button-hidden' : colFilter.disableCancelFilterButton === true }\">" +
  "<div ng-if=\"colFilter.type !== 'select'\"><input type=\"text\" class=\"input-sm form-control\" ng-model=\"colFilter.term\" ng-model-options=\"{ debounce : { 'default' : 300, 'blur' : 0 }}\" ng-attr-placeholder=\"{{colFilter.placeholder || ''}}\" aria-label=\"{{colFilter.ariaLabel || aria.defaultFilterLabel}}\"><div role=\"button\" class=\"ui-grid-filter-button\" ng-click=\"removeFilter(colFilter, $index)\" ng-if=\"!colFilter.disableCancelFilterButton\" ng-disabled=\"colFilter.term === undefined || colFilter.term === null || colFilter.term === ''\" ng-show=\"colFilter.term !== undefined && colFilter.term !== null && colFilter.term !== ''\"><i class=\"ui-grid-icon-cancel\" ui-grid-one-bind-aria-label=\"aria.removeFilter\">&nbsp;</i></div></div>" +
  "<div ng-if=\"colFilter.type === 'select'\"><select class=\"form-control input-sm\" ng-model=\"colFilter.term\" ng-attr-placeholder=\"{{colFilter.placeholder || aria.defaultFilterLabel}}\" aria-label=\"{{colFilter.ariaLabel || ''}}\" ng-options=\"option.value as option.label for option in colFilter.selectOptions\"><option value=\"\"></option></select><div role=\"button\" class=\"ui-grid-filter-button-select\" ng-click=\"removeFilter(colFilter, $index)\" ng-if=\"!colFilter.disableCancelFilterButton\" ng-disabled=\"colFilter.term === undefined || colFilter.term === null || colFilter.term === ''\" ng-show=\"colFilter.term !== undefined && colFilter.term != null\"><i class=\"ui-grid-icon-cancel\" ui-grid-one-bind-aria-label=\"aria.removeFilter\">&nbsp;</i></div></div>" +
  "</div>"
);
Run Code Online (Sandbox Code Playgroud)

这个工作的最后一步是在每个启用过滤的columnDef中设置此模板:

columnDefs: [{
  name: 'theName',
  displayName: 'Whatever',
  filterHeaderTemplate: 'ui-grid/ui-grid-filter-custom'
}]
Run Code Online (Sandbox Code Playgroud)

不幸的是,我找不到任何方法来全局定义这个模板,所以我不得不在任何地方重复filterHeaderTemplate ...这是唯一的缺点,但另一方面,如果你需要,你也可以为你的自定义模板添加更多的过滤器至.

希望能帮助到你!