J'ai déjà implémenté la pagination. Maintenant, je veux que la pagination soit mise à jour après avoir filtré mes résultats.
La forme:
<input type="text" data-ng-model="search.name" data-ng-change="filter()"/>
La liste:
<li data-ng-repeat="data in filtered = (list | filter:search) | filter:search | startFrom:(currentPage-1)*entryLimit | limitTo:entryLimit">{{data.name}}</li>
La pagination:
<pagination data-boundary-links="true" data-num-pages="noOfPages" data-current-page="currentPage" max-size="maxSize"></pagination>
Le controlle:
$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);
};
Mon problème est que la pagination est juste mise à jour après avoir cliqué sur un numéro de page ou après avoir entré le caractère suivant dans le champ de saisie. Il s'agit donc de mettre à jour une étape trop tard.
[~ # ~] modifier [~ # ~] : j'ai ajouté la source à jsFiddle: http://jsfiddle.net/eqCWL/2 /
Utilisation $timeout
au lieu de window.setTimeOut
. $timeout
est correctement enveloppé pour fonctionner de manière cohérente dans Angular.
@abject_error's answer using $timeout
fonctionne. J'ai édité votre violon avec sa suggestion et l'ai fait jsFiddle
[~ # ~] mise en garde [~ # ~]
Je pense que la solution indique un problème plus important sous la forme d'une condition de concurrence!
et ce violon est le chemin pour les vrais.
Et voici l'explication
Votre condition de concurrence entre la gestion du changement de search
et la disponibilité de $scope.filtered
.
Je pense que les coupables à éliminer pour résoudre cette condition de concurrence sont:
ng-model="search" ng-change="filter()"
et
ng-repeat="data in filtered = (list | filter:search)......."
En utilisant ng-change
pour déclencher "filter ()" pour faire le calcul de noOfPages
mais aussi en fonction d'un changement de recherche afin de créer filtered
. En procédant de cette façon, vous vous assurez que la liste filtrée ne peut pas être prête à temps pour calculer le nombre de pages, et c'est pourquoi entravant "filter ()" de 10 ms avec un délai d'attente vous donne l'illusion d'un programme de travail.
Ce dont vous avez besoin est un moyen de "surveiller" search
les modifications, puis de filtrer la liste à un endroit où vous avez accès à la fois à la création de $scope.filtered
et calcul $scope.noOfPages
. Tout en séquence, sans course.
Angular a cette façon! Il est possible d'utiliser le filtre filter
dans votre contrôleur comme fonction très mal nommée: filterFilter
. Vérifiez cela dans le Guide des filtres - Utilisation de filtres dans les contrôleurs et les services
Injectez-le dans le contrôleur.
function pageCtrl($scope, filterFilter) {
// ...
}
Utilisez-le dans un $watch
fonction, documentée dans les 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);
})
Modifiez le modèle pour refléter notre nouvelle façon. Plus de filtre DOM, ou ng-change
<input type="text" ng-model="search" placeholder="Search"/>
et
<li ng-repeat="data in filtered | startFrom:(currentPage-1)*entryLimit | limitTo:entryLimit">
{{data.name}}
</li>
Vous pouvez simplement utiliser cette directive à la place:
https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination
Il offre une pagination avec un filtre tout en gardant le code Nice et propre.
Félicitations à Michaelbromley pour le grand code.
Utilisez angular $scope.$watch
$scope.$watch('search', function(term) {
$scope.filter = function() {
$scope.noOfPages = Math.ceil($scope.filtered.length/$scope.entryLimit);
}
});
La source ; http://jsfiddle.net/eqCWL/2/