2016-12-27 2 views
0

Ich habe einen Abfrageservice in AngularJS geschrieben und möchte den Dienst starten, wenn meine Postanforderung erledigt ist. Aber wenn ich die GUI anrufe, ist der Abfrageservice aktiv.Kann ich den Abrufdienst per Anruf starten? AngularJS

ich habe versuchen, eine Start-Funktion, Ende-Funktion zu implementieren und die start() Funktion aufrufen, wenn der Post-Anforderung erfolgt .. aber es funktioniert nicht:/

Meine Umfrage Service:

.factory('NotificationPollService', 
['$http', '$q', '$interval', 
function ($http, $q, $interval) { 

    var deferred = $q.defer(); 
    var notification = {}; 

    notification.poller = $interval(function(id) { 
     $http.get('http://localhost:9999/v1/jmeter/id', {cache: false}) 
     .success(function(data, status, headers, config) { 
      return data; 
     }, 10000); 
    }); 

    notification.endPolling = function() {$interval.cancel(this.interval);};  

}])

und die Steuerung, die ich die Anfrage schreiben

.controller('HomeController', 
['$scope', '$rootScope', 'SendJmeterFile', 'NotificationPollService', 
function ($scope, $rootScope, SendJmeterFile , NotificationPollService) { 

    $scope.upload = function() { 

     var customArtifacts = ""; 
     var testDataBase = ""; 

     if($scope.jmeterFile.customArtifact == undefined){ 
      customArtifacts = null; 
     } else {customArtifacts = $scope.jmeterFile.customArtifact.base64} 

     if($scope.jmeterFile.testDataBase == undefined){ 
      testDataBase = null; 
     } else {testDataBase = $scope.jmeterFile.testDataBase.base64} 

     SendJmeterFile.upload($scope.jmeterFile.jmeter.base64, customArtifacts, $scope.jmeterFile.customProperties, $scope.jmeterFile.instanceConfiguration, $scope.jmeterFile.instances, $scope.jmeterFile.providerID, testDataBase) 
      .then(function(data) { 
       alert("Daten erfolgreich verschickt!"); 
       console.log(data); 
       NotificationPollService.poller(data.id) 
       //.then(function(data) { 
        /*if(data.status == "SETUP") 

        if(data.status == "TEST") 

        if(data.status == "DONE") 

        if(data.status == "ERROR") 
       }), function(data) { 
        })*/ 
      }, function(data) { 
       alert("Fehler!"); 
       console.log(data); 
      });  
    }; 
}]) 

Antwort

0

Ein Problem ist, dass $interval() sofort nach der Injektion in Ihren Controller aufgerufen wird. Ihre Idee, eine "Start" -Methode oder etwas Ähnliches zu implementieren, war eine gute - aber Sie können es wahrscheinlich noch mehr vereinfachen, indem Sie die Fabrik eine Funktion zurückgeben lassen. Dann können Sie diese Funktion in Ihrem Controller so oft instanziieren, wie Sie einen Poller benötigen.

Allerdings gibt es mehr Probleme. Ein Versprechen kann nur einmal gelöst werden, und da Sie eine HTTP-Anfrage mehrere Male ausführen, ist meine Vermutung, dass Sie über Statusänderungen "benachrichtigt" werden sollen, bis der Status als "Fertig" markiert ist. Sie beauftragen derzeit, den Status mit dem Controller zu überprüfen. Wenn Sie jedoch nur über die Schritte "Fehler" und "Erfolg" informiert werden möchten, ist es wahrscheinlich besser, den Dienst Poller für die Interpretation der Statusinformationen verantwortlich zu machen, die von Ihrem Dienst stammen, und einfach vom Standardversprechen abhängig zu sein in deinem Controller. Ich entschied mich ein Beispiel für letzteren Fall zu zeigen:

UPDATE: Probe plnkr hier: http://plnkr.co/edit/e7vqU82fqYGQuCwufPZN?p=preview

angular.module('MYMODULENAMEHERE') 
.factory('NotificationPoller', 
    ['$http', '$q', '$interval', 
    function ($http, $q, $interval) { 

     return poller; 

     function poller(id) { 
      var _this = this; 
      var deferred = $q.defer(); 

      var interval = $interval(function() { 
       $http 
        // I assumed you actually want to use the value of 'id' in your 
        // url here, rather than just the word 'id'. 
        .get('http://localhost:9999/v1/jmeter/' + id, {cache: false}) 
        .then(function(data, status, headers, config) { 
         // I commented out the following statement. It is meaningless because 
         // you can't do anything with the return value since it's an anonymous 
         // function you're returning it from. Instead, you probably meant to 
         // use the promise to return the data. 

         // return data; 

         if(data.status == "SETUP") { 
          deferred.notify(data); 
         } 
         else if(data.status == "TEST") { 
          deferred.notify(data); 
         } 
         else if(data.status == "DONE") { 
          _this.endPolling(); // Automatically stop polling when status is done 
          deferred.resolve(data); 
         } 
         else { // data.status == "ERROR" (or anything else that's not expected) 
          _this.endPolling(); // Automatically stop polling on error 
          deferred.reject(data); 
         }      
        }, function(data) { 
         _this.endPolling(); 
         deferred.reject(data); 
        }); 
      }, 10000); 

      this.endPolling = function() { 
       $interval.cancel(interval); 
      }; 

      // Make the promise available to calling code 
      this.promise = deferred.promise; 
     }; 
}]) 

Jetzt ist Ihr Controller kann viel leichter Ihre Polling Service nutzen. Hier ist ein Beispiel für eine abgespeckte Controller Ihre Abfragedienst für Klarheit:

angular.module('MYMODULENAMEHERE') 
.controller('HomeController', [ 
    'NotificationPoller', 
    function(NotificationPoller) { 

     var some_id = 207810; 

     var poller = new NotificationPoller(some_id); 
     poller.promise.then(onSuccess, onError, onNotify); 

     function onSuccess(data) { 
      // data.status == "DONE" 
     }; 

     function onError(data) { 
      // data.status == "ERROR" 
     }; 

     function onNotify(data) { 
      // data.status == "TEST" || data.status == "SETUP" 
     }; 

    }]); 

Wie Sie sehen, ist die Fabrik ein wenig mehr Verantwortung auf diese Weise erhalten, aber der Controller muss nicht bewusst sein, die Details aller Status, die das Backend nicht mehr senden kann. Es verwendet nur Standardversprechen.

+0

danke für diese hilfreiche Antwort! Ich habe es versucht und bekomme den Fehler, dass NotificationPollService kein Konstruktor ist, kann ich den NotificationPollService in der SendJMeterFile.upload.then .. Erfolgsfunktion initialisieren? – Kai

+0

Dies ist ein guter Fall Szenario meiner Aufgabe: Senden Sie die Datei an den Server, der Server führen Sie es aus und setzen Sie den Status hängt von dem Schritt der Server (running, done, error, test) und in dieser Zeit möchte ich abfragen der Dienst mit der ID der Antwort des Servers. also ich denke, ich rufe den Poll-Service auf den Erfolgsfall nach der Post Anfrage oder bin ich falsch? – Kai

+0

Ja, das ist die Annahme, die ich basierend auf Ihrem ursprünglichen Code gemacht habe. Ich bin nicht sicher, warum Sie diesen Fehler erhalten, obwohl es etwas mit der Tatsache zu tun haben könnte, dass Sie meinen Code möglicherweise direkt kopiert haben? Es wird nicht funktionieren, weil ich in den Beispielskripten kein Winkelmodul definiert habe. Ich habe für Sie einen Plnkr erstellt, der funktioniert (natürlich ohne das eigentliche Backend), also können Sie vielleicht nachsehen, ob Ihnen das besser hilft: http://plnkr.co/edit/e7vqU82fqYGQuCwufPZN?p = Vorschau –

0

Sie tr y NotificationPollService.poller(data.id) zu nennen, die Promise ist, eigentlich, weil zuvor in NotificationPollService Sie notification.poller zugewiesen wie so

notification.poller = $interval(function(id) { 
    $http.get('http://localhost:9999/v1/jmeter/id', {cache: false}) 
    .success(function(data, status, headers, config) { 
     return data; 
    }, 10000); 
}); 

Jetzt ist Ihr notification.poller ist ein Rückgabewert von $interval Funktion. Um es funktionieren zu lassen, sollten Sie die Funktion umbrechen, so dass Sie tatsächlich eine ID an sie übergeben können.

+0

Wenn ich den NotificationPollService.poller (data.id) lösche, ist die Intervallfunktion noch aktiv, wenn ich eine Datei hochlade:/was meinst du mit wrap the function? i – Kai

+0

Ich nahm an, dass Alarm ('Daten erfolgreich versendet!') tatsächlich eine Zeichenfolge alarmierte. Ist das richtig? – antonama

+0

ja es ist nur eine Benachrichtigung für mich, dass ich sehe, dass die Post-Anfrage funktioniert ^^ – Kai

Verwandte Themen