J'interroge mes données toutes les 2 secondes pour les garder à jour sur la page. Mon problème est que lorsque je visite une autre page, le délai reste actif. Comment puis-je annuler mon délai d'expiration lorsque je visite une nouvelle page?
function IndexCtrl($scope, $timeout, RestData) {
$scope.rd = {};
(function getRestDataFromServer() {
RestData.query(function(data){
$scope.rd = data;
$timeout(getRestDataFromServer, 2000);
});
})();
}
// EDIT J'ai trouvé une solution, mais je ne sais pas si elle est bonne. Lorsque j'enregistre mon délai d'expiration sur $ rootScope, je peux l'annuler dans tous les autres contrôleurs.
function IndexCtrl($scope, $rootScope, $timeout, RestData) {
$scope.rd = {};
(function getRestDataFromServer() {
RestData.query(function(data){
$scope.rd = data;
$rootScope.prom = $timeout(getRestDataFromServer, 2000);
});
})();
}
function newPageCtrl($scope, $rootScope, $timeout) {
$timeout.cancel($rootScope.prom);
}
Il y a quelques Angular qui sont diffusés lorsque l'itinéraire est modifié. Vous pouvez les écouter dans le IndexCtrl
en utilisant $scope.$on
Et agir en conséquence:
événement $ destroy
var promise = $timeout(getRestDataFromServer, 2000);
...
$scope.$on('$destroy', function(){
$timeout.cancel(promise);
});
$ locationChangeStart
var promise = $timeout(getRestDataFromServer, 2000);
...
$scope.$on('$locationChangeStart', function(){
$timeout.cancel(promise);
});
$timeout()
renvoie un objet promis. Cet objet peut être fourni à la fonction $timeout.cancel()
pour annuler le délai d'attente.
La réponse de Stewie est parfaite. Je voulais juste partager cette fonction d'aide simple que j'utilise au lieu d'utiliser directement $timeout
, De sorte que je n'ai plus jamais à penser à ce problème:
function setTimeout(scope, fn, delay) {
var promise = $timeout(fn, delay);
var deregister = scope.$on('$destroy', function() {
$timeout.cancel(promise);
});
promise.then(deregister, deregister);
}
J'ai ajouté cette fonction à un service appelé miscUtils
, et j'injecte ce service au lieu d'injecter $timeout
. Ensuite, par exemple, pour créer une fonction "mise à jour" qui s'exécute toutes les 30 secondes jusqu'à ce que $scope
Soit détruit:
update();
function update() {
// do the actual updating here
miscUtils.setTimeout($scope, update, 30000);
}
Modifier pour ceux qui ne savent pas ce qui se passe avec deregister
:
Cette fonction enregistre un écouteur pour l'événement $destroy
, Mais une fois le délai d'attente terminé, il n'est plus nécessaire; il n'y a plus de délai d'expiration pour annuler. scope.$on
renvoie une fonction qui, lorsqu'elle est appelée, désenregistre cet écouteur. Ainsi, promise.then(deregister)
nettoie cet écouteur dont vous n'avez plus besoin dès que le délai est écoulé.