6

サーバー側の並べ替え、サーバー側のページネーション、およびサーバー側のフィルタリングを使用して、Angular でグリッドを実装しようとしています。ui-grid (不安定) を使用して、ui.grid.paging を追加し、すべてを稼働させました。開発者に感謝します。

ただし.... $scope.gridApi.core.on.filterChanged はキーが押されるたびに発生するため、givenname 列で「Patrick」を検索すると、7 つのイベントが発生し、7 つの get-request がサーバーにヒットします。さらに悪いことに、私がフィルタリングしているのは大きなセットであるため、この操作はかなり高価であり、最も具体的なフィルターが最速の結果を取得するように、結果は互いに追い越し、あまり具体的でない結果が処理される前に成功を引き起こします。

「進入停止後に発火」のようにスローダウンさせたい。私は JavaScript と REST にかなり慣れていません。これは私の最初の現実世界のプロジェクトです。この問題を処理する方法についてのアイデアをいただければ幸いです。これは一般的なシナリオのように感じられるため、標準的なソリューションやベスト プラクティスが欠けている可能性があります。

あなたの、パトリック。

4

4 に答える 4

16

「すべての角度」に行きたい場合は、イベントハンドラー$timeout内で使用することをお勧めします。on.filterChanged

if (angular.isDefined($scope.filterTimeout)) {
    $timeout.cancel($scope.filterTimeout);
}
$scope.filterTimeout = $timeout(function () {
    getPage();
}, 500);

ここで、500 は各 on.filterChanged イベント間でサーバーにアクセスする前に待機する時間 (ミリ秒単位) であり、getPage() は実際にサーバーにアクセスしてデータを取得する関数です。

$timeoutコントローラーの「destroy」イベントでキャンセルすることを忘れないでください。

$scope.$on("$destroy", function (event) {
    if (angular.isDefined($scope.filterTimeout)) {
        $timeout.cancel($scope.filterTimeout);
    }
});
于 2014-12-04T22:32:05.747 に答える
9

私は同じ問題を扱っていましたが、私見がより「角度に優しい」別の解決策を思いつきました。 Angular 1.3 で導入されたngModelOptions ディレクティブを使用しました。uiGrid の既定のフィルター テンプレート ("ui-grid/ui-grid-filter") をカスタム テンプレートに置き換え、入力の ngModelOptions ディレクティブを既定のデバウンス値 300 ミリ秒とぼかし用の 0 ミリ秒に構成しました。

これは 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>"
);

これを機能させるための最後の手順は、フィルタリングを有効にするすべての columnDef でこのテンプレートを設定することです。

columnDefs: [{
  name: 'theName',
  displayName: 'Whatever',
  filterHeaderTemplate: 'ui-grid/ui-grid-filter-custom'
}]

残念ながら、このテンプレートをグローバルに定義する方法が見つからなかったので、どこでも filterHeaderTemplate を繰り返さなければなりませんでした...それが唯一の欠点ですが、必要に応じてカスタム テンプレートにフィルターを追加することもできます。に。

それが役に立てば幸い!

于 2015-09-12T21:52:15.503 に答える
0

以下に示すように、 JavaScriptのsetTimeout関数を使用して遅延を与えることもできます。

$scope.gridApi.core.on.filterChanged( $scope, function() {

    if (angular.isDefined($scope.filterTimeout)) {
        clearTimeout($scope.filterTimeout);
    }
    $scope.filterTimeout = setTimeout(function(){
        getPage();
    },1000);

});
于 2016-02-15T07:32:57.627 に答える