Comment effacer ou arrêter timeInterval dans angularjs?

91

Je fais une démo dans laquelle je récupère des données du serveur après des intervalles de temps réguliers en utilisant $intervalMaintenant, je dois arrêter / annuler cela.

Comment puis-je y parvenir? Si j'ai besoin de redémarrer le processus, comment dois-je le faire?

Deuxièmement, j'ai une autre question: je récupère les données du serveur après des intervalles de temps requis. Est-il nécessaire d'utiliser $scope.applyou $scope.watch?

Voici mon plunker:

  app.controller('departureContrl',function($scope,test, $interval){
   setData();

   $interval(setData, 1000*30);

   function setData(){
      $scope.loading=true;
    test.stationDashBoard(function(data){
        console.log(data);
        $scope.data=data.data;
        $scope.loading=false;
        //alert(data);
    },function(error){
        alert('error')
    }) ;

   }
});

http://plnkr.co/edit/ly43m5?p=preview

user944513
la source

Réponses:

158

Vous pouvez stocker la promesse retournée par l'intervalle et l'utiliser $interval.cancel()pour cette promesse, ce qui annule l'intervalle de cette promesse. Pour déléguer le démarrage et l'arrêt de l'intervalle, vous pouvez créer des fonctions start()et des stop()fonctions chaque fois que vous souhaitez les arrêter et les redémarrer à partir d'un événement spécifique. J'ai créé un extrait ci-dessous montrant les bases du démarrage et de l'arrêt d'un intervalle, en l'implémentant en vue via l'utilisation d'événements (par exemple ng-click) et dans le contrôleur.

angular.module('app', [])

  .controller('ItemController', function($scope, $interval) {
  
    // store the interval promise in this variable
    var promise;
  
    // simulated items array
    $scope.items = [];
    
    // starts the interval
    $scope.start = function() {
      // stops any running interval to avoid two intervals running at the same time
      $scope.stop(); 
      
      // store the interval promise
      promise = $interval(setRandomizedCollection, 1000);
    };
  
    // stops the interval
    $scope.stop = function() {
      $interval.cancel(promise);
    };
  
    // starting the interval by default
    $scope.start();
 
    // stops the interval when the scope is destroyed,
    // this usually happens when a route is changed and 
    // the ItemsController $scope gets destroyed. The
    // destruction of the ItemsController scope does not
    // guarantee the stopping of any intervals, you must
    // be responsible for stopping it when the scope is
    // is destroyed.
    $scope.$on('$destroy', function() {
      $scope.stop();
    });
            
    function setRandomizedCollection() {
      // items to randomize 1 - 11
      var randomItems = parseInt(Math.random() * 10 + 1); 
        
      // empties the items array
      $scope.items.length = 0; 
      
      // loop through random N times
      while(randomItems--) {
        
        // push random number from 1 - 10000 to $scope.items
        $scope.items.push(parseInt(Math.random() * 10000 + 1)); 
      }
    }
  
  });
<div ng-app="app" ng-controller="ItemController">
  
  <!-- Event trigger to start the interval -->
  <button type="button" ng-click="start()">Start Interval</button>
  
  <!-- Event trigger to stop the interval -->
  <button type="button" ng-click="stop()">Stop Interval</button>
  
  <!-- display all the random items -->
  <ul>
    <li ng-repeat="item in items track by $index" ng-bind="item"></li>
  </ul>
  <!-- end of display -->
</div>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

seigle
la source
@merci pour la réponse ..est-il nécessaire d'ajouter appliquer ou regarder lorsque je récupère des données à partir de l'intervalle de temps
requis
Non, vous n'avez pas besoin d'utiliser apply(), si vous utilisez le $intervalservice, car il le fait pour vous. Mais si vous utilisez la fonction intégrée, setInterval()vous devrez peut-être utiliser $scope.$apply().
ryeballar
Très bonne solution. Le $destroyfonctionne bien avec la http-auth-interceptorcomme dans mon cas où je veux arrêter l'intervalle pendant auth échec (comme la session a expiré) et recommencer après succesfull auth. Merci pour cette excellente solution.
Neel
37
var interval = $interval(function() {
  console.log('say hello');
}, 1000);

$interval.cancel(interval);
Arun Sharma
la source
9
var promise = $interval(function(){
    if($location.path() == '/landing'){
        $rootScope.$emit('testData',"test");
        $interval.cancel(promise);
    }
},2000);
Jijo Paulose
la source
Étant donné que les URL peuvent changer à l'avenir, j'y réfléchirais à deux fois avant d'utiliser le $location.path()nom de l'état et non le nom de l'état
Ou Duan
1
    $scope.toggleRightDelayed = function(){
        var myInterval = $interval(function(){
            $scope.toggleRight();
        },1000,1)
        .then(function(){
            $interval.cancel(myInterval);
        });
    };
Christian Bonato
la source
1

Lorsque vous souhaitez créer une promesse de stockage d'intervalle à variable:

var p = $interval(function() { ... },1000);

Et lorsque vous souhaitez arrêter / effacer l'intervalle, utilisez simplement:

$interval.cancel(p);
pixparker
la source