it-swarm.com.de

Aktualisieren Sie die Paginierung in AngularJS nach dem Filtern

Ich habe die Paginierung bereits implementiert. Jetzt möchte ich, dass die Paginierung nach dem Filtern meiner Ergebnisse aktualisiert wird.

Die Form:

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

Die Liste:

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

Die Paginierung:

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

Der Controller:

$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);
};

Mein Problem ist, dass die Paginierung nur aktualisiert wird, nachdem Sie auf eine Seitenzahl geklickt oder das nächste Zeichen in das Eingabefeld eingegeben haben. Das Update ist also einen Schritt zu spät.

[~ # ~] edit [~ # ~] : Ich habe die Quelle zu jsFiddle hinzugefügt: http://jsfiddle.net/eqCWL/2 /

34
StinsonMaster

Verwenden $timeout Anstatt von window.setTimeOut. $timeout wird ordnungsgemäß verpackt, um in Angular konsistent zu arbeiten.

3
abject_error

Antwort von @abject_error mit $timeout funktioniert. Ich habe deine Geige mit seinem Vorschlag bearbeitet und dies gemacht jsFiddle

[~ # ~] Einschränkung [~ # ~]

Ich denke, die Lösung deutet auf ein größeres Problem in Form einer Rennbedingung hin!

jsFiddle benutzt filterFilter und $ watch

und diese Geige ist die Art und Weise, wie es wirklich geht.

Und hier ist die Erklärung

Ihre Wettkampfbedingung liegt zwischen der Bearbeitung der Änderung von search und der Verfügbarkeit von $scope.filtered.

Ich denke, die Schuldigen, die beseitigt werden müssen, um diese Rennbedingung zu lösen, sind:

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

und

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

Mit ng-change "filter ()" auslösen, um die Berechnung von noOfPages durchzuführen, aber auch abhängig von einer Änderung in der Suche, um filtered zu erstellen. Auf diese Weise wird sichergestellt, dass die gefilterte Liste möglicherweise nicht rechtzeitig zur Berechnung der Seitenzahl bereit ist. Wenn Sie daher "filter ()" mit einer Zeitüberschreitung um 10 ms humpeln, entsteht die Illusion eines Arbeitsprogramms.

Was Sie brauchen, ist eine Möglichkeit, search auf Änderungen zu "beobachten" und dann die Liste an einem Ort zu filtern, an dem Sie Zugriff auf beide haben, die $scope.filtered und Berechnung $scope.noOfPages. Alles nacheinander, ohne Rennen.

Angular hat so! Es ist möglich, den Filter filter in Ihrem Controller als sehr schlecht benannte Funktion zu verwenden: filterFilter. Überprüfen Sie dies im Filterhandbuch - Verwenden von Filtern in Controllern und Diensten

Injizieren Sie es in die Steuerung.

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

Verwenden Sie es in einem $watch Funktion, dokumentiert in Scopes Docs

$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);  
})

Ändern Sie die Vorlage, um unseren neuen Weg widerzuspiegeln. Nicht mehr im DOM-Filter oder ng-change

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

und

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

Sie können stattdessen einfach diese Anweisung verwenden:

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

Es bietet Paginierung mit einem Filter, während der Code schön und sauber bleibt.

Ein großes Lob an michaelbromley für den tollen Code.

4
peppydip

Verwenden Sie angular $scope.$watch

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

Quelle ; http://jsfiddle.net/eqCWL/2/

Demo; http://jsfiddle.net/eqCWL/192/

2
sinHoot