Wie lösche oder stoppe ich timeInterval in anglejs?

91

Ich mache eine Demo, in der ich nach regelmäßigen Zeitabständen Daten vom Server abrufe. $intervalJetzt muss ich dies stoppen / abbrechen.

Wie kann ich das erreichen? Wie soll ich das tun, wenn ich den Prozess neu starten muss?

Zweitens habe ich noch eine Frage: Ich rufe nach regelmäßigen Zeitintervallen Daten vom Server ab. Gibt es eine Notwendigkeit zu verwenden $scope.applyoder $scope.watch?

Hier ist mein 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
quelle

Antworten:

158

Sie können das vom Intervall zurückgegebene Versprechen speichern und $interval.cancel()für dieses Versprechen verwenden, wodurch das Intervall dieses Versprechens abgebrochen wird. Um das Starten und Stoppen des Intervalls zu delegieren, können Sie erstellen start()und stop()funktionieren, wann immer Sie sie stoppen und von einem bestimmten Ereignis aus erneut starten möchten. Ich habe unten ein Snippet erstellt, das die Grundlagen zum Starten und Stoppen eines Intervalls zeigt, indem es in der Ansicht mithilfe von Ereignissen (z. B. ng-click) und im Controller implementiert wird.

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>

Roggenballar
quelle
@ danke für die Antwort ..ist es notwendig, anwenden oder beobachten, wenn ich Daten aus dem Dienst Zeitintervall
abrufe
Nein, Sie müssen nicht verwenden apply(), wenn Sie den $intervalDienst verwenden, da er dies für Sie erledigt. Wenn Sie jedoch das integrierte setInterval()Gerät verwenden, müssen Sie es möglicherweise verwenden $scope.$apply().
Roggenballar
Sehr gute Lösung. Das $destroyfunktioniert gut zusammen mit http-auth-interceptorÄhnlichem in meinem Fall, wo ich das Intervall während eines Authentifizierungsfehlers (wie abgelaufene Sitzung) stoppen und nach erfolgreicher Authentifizierung erneut starten möchte. Vielen Dank für diese hervorragende Lösung.
Neel
37
var interval = $interval(function() {
  console.log('say hello');
}, 1000);

$interval.cancel(interval);
Arun Sharma
quelle
9
var promise = $interval(function(){
    if($location.path() == '/landing'){
        $rootScope.$emit('testData',"test");
        $interval.cancel(promise);
    }
},2000);
Jijo Paulose
quelle
Da sich URLs in Zukunft möglicherweise ändern, würde ich zweimal überlegen, bevor ich den $location.path()und nicht den Statusnamen verwende
oder Duan
1
    $scope.toggleRightDelayed = function(){
        var myInterval = $interval(function(){
            $scope.toggleRight();
        },1000,1)
        .then(function(){
            $interval.cancel(myInterval);
        });
    };
Christian Bonato
quelle
1

Wenn Sie ein Intervallspeicherversprechen für eine Variable erstellen möchten:

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

Und wenn Sie das Intervall stoppen / löschen möchten, verwenden Sie einfach:

$interval.cancel(p);
pixparker
quelle