Es gibt die Möglichkeit über einen Frontend Listener auf Background Prozesse zu hören. Das ist sicher nicht die Best-Practice, aber schnell und einfach Implementiert. Gerade bei der Auswertung von Background-Prozessen, z.B. für eine Progressbar, ist das sehr hilfreich. Also wenn es einen User betrifft. Allen Usern sollte man so etwas nicht gleichzeitig zur Verfügung stellen. Generell sollte ein solcher Listener explizit gestartet und gestoppt werden. Denn wenn es keinen Prozess gibt, der beobachtet werden muß. Das ist in dem folgenden AngularJS-Codebeispiel sehr gut gewährleistet.
AngularJS Interval AJAX Listener
Basierend auf der AngularJS Dokumentation zu $interval beschreibe ich nun die Vorgehensweise. Als Beispiel gibt es hier einen Kampf, bei dem Bluteinheiten verloren werden.
1 2 3 4 5 6 7 8 9 |
<script type="text/javascript">// <![CDATA[ angular.module('intervalExample', []) .controller('ExampleController', ['$scope', '$interval', function($scope, $interval) { $scope.format = 'M/d/yy h:mm:ss a'; $scope.blood_1 = 100; $scope.blood_2 = 120; |
Im ersten Teil wird der AngularJS-Controller initialisiert und mit Standard Werten gefüllt. Man beachte hier den Aufbau des AngularJS-Controllers. Er wird in der Array-Notation realisiert. Das wird so von den AngularJS-Webdevelopern empfohlen und in den zahlreichen AngularJS-Api Beispielen auch realisiert. Es entspricht also einem Cleancode-Standard. Das sollte man auch immer bei den eigenen Scripten tun. In anderen AngularJS-Beispielen, die man so im Netz findet, wird das häufig nicht gemacht. Bei dem Datum wird zusätzlich noch mit einem Filter gearbeitet. Da gehe ich in diesem Artikel allerdings nicht drauf ein. Hier nun die erste Funktion bzw. Methode
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
var stop; $scope.fight = function() { // Don't start a new fight if we are already fighting if ( angular.isDefined(stop) ) return; stop = $interval(function() { if ($scope.blood_1 > 0 && $scope.blood_2 > 0) { $scope.blood_1 = $scope.blood_1 - 3; $scope.blood_2 = $scope.blood_2 - 4; } else { $scope.stopFight(); } }, 100); }; |
Die AngularJS-Variable stop wird definiert und dann in der eigentlichen Fight-Methode mit der Interval-Funktion befüllt. So wird, wie im Kommentar bereits erwähnt verhindet, daß 2 Kämpfe laufen. Am Ende der AngularJS-Interval-Funktion steht der Wert 100 für die Millisekunden. Das ist für einen solchen reinen AngularJS-Prozess auch gut, nutzt man hier allerdings einen AJAX-Request gegen einen Webservice sollte man hier auf einige Sekunden erhöhen. Hat einer der beiden Kämpfer kein Blut mehr, endet der Kampf und in Else-Teil wird die stopFight()-Methode aufgerufen.
1 2 3 4 5 6 |
$scope.stopFight = function() { if (angular.isDefined(stop)) { $interval.cancel(stop); stop = undefined; } }; |
Bei der wird der Interval durch die cancel-Methode unterbrochen und stop als undefined definiert. So stoppt der Interval.
1 2 3 4 |
$scope.resetFight = function() { $scope.blood_1 = 100; $scope.blood_2 = 120; }; |
Hier ist noch die resetFight-Methode. Hier bekommen die beiden Kämpfer wieder ihr Blut aufgefüllt und können wieder loslegen.
1 2 3 4 |
$scope.$on('$destroy', function() { // Make sure that the interval is destroyed too $scope.stopFight(); }); |
Zu guter letzt werden ist noch eine Fallback-Methode für den Interval definiert, damit die stopFight-Methode auf jeden Fall ausgeführt wird.
Über den Autor
Roland Golla ist Cleancode-Developer und bei einem eCommerce-Unternehmen zuständig für Codestandards und Software-Qualität. Als Webdeveloper realisiert er dort auch ein Projekt mit dem PHP-Framework Symfony als Data-Provider und AngularJS als Web Application Frontend.