web-dev-qa-db-ja.com

フィルタリング後にAngularJSのページネーションを更新

私はすでにページネーションを実装しています。ここで、結果をフィルタリングした後、ページネーションを更新する必要があります。

フォーム:

<input type="text" data-ng-model="search.name" data-ng-change="filter()"/>

リスト:

<li data-ng-repeat="data in filtered = (list | filter:search) | filter:search | startFrom:(currentPage-1)*entryLimit | limitTo:entryLimit">{{data.name}}</li>

ページネーション:

<pagination data-boundary-links="true" data-num-pages="noOfPages" data-current-page="currentPage" max-size="maxSize"></pagination>

コントローラー:

$scope.filter = function() {
    window.setTimeout(function() { //wait for 'filtered' to be changed
        $scope.noOfPages = Math.ceil($scope.filtered.length/$scope.entryLimit);
        $scope.setPage = function(pageNo) {
            $scope.currentPage = pageNo;
        };
    }, 10);
};

私の問題は、ページ番号をクリックした後、または入力フィールドに次の文字を入力した後、ページネーションが更新されることです。ですから、一歩遅れて更新されます。

[〜#〜] edit [〜#〜]:jsFiddleにソースを追加しました: http://jsfiddle.net/eqCWL/2 /

34
StinsonMaster

つかいます $timeout の代わりに window.setTimeOut$timeoutは、Angularで一貫して動作するように適切にラップされます。

3
abject_error

$timeoutを使用した@abject_errorの回答は機能します。彼の提案でフィドルを編集し、これを作成しました jsFiddle

[〜#〜] caveat [〜#〜]

この解決策は、競合状態というより大きな問題を示していると思います!

filterFilterと$ watchを使用したjsFiddle

そして、そのフィドルは、実際にはそれを回避する方法です。

そしてここに説明があります

競合状態は、searchの変更の処理と$scope.filteredの可用性の間にあります。

この競合状態を解決するために排除すべき犯人は次のとおりです。

ng-model="search" ng-change="filter()"

そして

ng-repeat="data in filtered = (list | filter:search)......."

ng-changeを使用して「filter()」を起動し、noOfPagesの計算を行いますが、filteredを作成するための検索の変更にも依存します。このようにすることで、ページ数を計算するためにフィルターされたリストが時間内に準備できなくなる可能性があります。そのため、タイムアウトで「filter()」を10ミリ秒ホブリングすると、プログラムが動作しているように見えます。

必要なのは、searchの変更を「監視」し、$scope.filteredの作成と$scope.noOfPagesの計算の両方にアクセスできる場所でリストをフィルタリングする方法です。すべて順を追って、レースなし。

Angularにはその方法があります! filterという名前の非常に貧弱な関数として、コントローラーでfilterFilterフィルターを使用することができます。 フィルターガイド-コントローラーおよびサービスでフィルターを使用する でこれを確認してください。

それをコントローラーに注入します。

function pageCtrl($scope, filterFilter) {
    // ...
}

scopes docs に文書化されている$watch関数で使用します

$scope.$watch('search', function(term) {  
    // Create filtered 
    $scope.filtered = filterFilter($scope.list, term);  

    // Then calculate noOfPages
    $scope.noOfPages = Math.ceil($scope.filtered.length/$scope.entryLimit);  
})

テンプレートを変更して、新しい方法を反映させます。 DOMフィルター、またはng-change

<input type="text" ng-model="search" placeholder="Search"/>

そして

<li ng-repeat="data in filtered | startFrom:(currentPage-1)*entryLimit | limitTo:entryLimit">
    {{data.name}}
</li>
36
nackjicholson

代わりにこのディレクティブを単純に使用できます。

https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination

コードをすっきりときれいに保ちながら、フィルターによるページネーションを提供します。

素晴らしいコードを提供してくれたmichaelbromleyに感謝します。

4
peppydip

angular $scope.$watch

$scope.$watch('search', function(term) {
    $scope.filter = function() {
        $scope.noOfPages = Math.ceil($scope.filtered.length/$scope.entryLimit);
    }
});

ソース; http://jsfiddle.net/eqCWL/2/

デモ ; http://jsfiddle.net/eqCWL/192/

2
sinHoot