2015-07-20 8 views
8

So habe ich herumgespielt mit dem Versprechen, in einem Service vs in einem Controller zu lösen. Ich würde es lieber im Service auflösen, damit ich die Variable wiederverwenden kann, ohne sie mehrfach auflösen zu müssen.Lösen eines Versprechens in einem Service/Fabrik vs in einem Controller mit AngularJS

Das Problem, das ich habe, ist, dass es funktioniert, aber es gibt die Daten sehr sehr langsam zurück. Ich fühle mich, als würde ich hier etwas falsch machen. Es dauert ungefähr 5 oder 6 Sekunden, bis meine ng-Optionen gefüllt sind. Welches ist besser? Und wie kann ich meinen Code verbessern, damit er schneller läuft?

In Service Entschlossen:

resortModule.factory('locaService',['$http', '$rootScope', function ($http, $rootScope){ 
    locaService.getLocations= 
     function() { 
      return $http.get('/api/destinations').then(
       function(result){ 
        locaService.locations= result.data; 
        return locaService.locations; 
       } 
      ); 
     return locaService.locations; 
    }; 
resortModule.controller('queryController',['$scope', 'locaService', function($scope, locaService) { 
    $scope.getLocations= locaService.getLocations().then(function(result){ 
     $scope.locations= result; 
    }); 
}]); 

in Controller-Entschlossen:

resortModule.factory('locaService',['$http', '$rootScope', function ($http, $rootScope){ 
locaService.getLocations= 
    function() { 
     locaService.locations= $http.get('/api/destinations'); 
     //stores variable for later use 
     return locaService.locations; 
    }; 
}]); 
resortModule.controller('queryController',['$scope', 'locaService',   
    function($scope, locaService) { 
     locaService.getLocations() 
     .then(
      function(locations) // $http returned a successful result 
      {$scope.locations = locations;} //set locations to returned data 
     ,function(err){console.log(err)}); 
}]); 

HTML:

<select ng-click="selectCheck(); hideStyle={display:'none'}" name="destination" ng-style="validStyle" ng-change="getResorts(userLocation); redirect(userLocation)" class="g-input" id="location" ng-model="userLocation"> 
    <option value=''>Select Location</option> 
    <option value='/destinations'>All</option> 
    <option value="{{loca.id}}" ng-repeat="loca in locations | orderBy: 'name'">{{loca.name}}</option> 
</select> 
+1

[Caching das Versprechen] (http://stackoverflow.com/a/18745499/1048572) ist viel einfacher als den Wert zwischenspeichern. – Bergi

+0

@Bergi danke für den Link. – allienx

Antwort

4

In Winkel Dienstleistungen sind Singletons so nur eine Instanz in der App gibt es . Auf diese Weise können Sie Daten in Ihrem Dienst auflösen, speichern und bei nachfolgenden Aufrufen die bereits aufgelösten Daten zurückgeben. Dadurch können Sie Ihre Daten nicht mehrfach auflösen und Ihre Logik zwischen Service und Controller getrennt halten.

UPDATE - Cache Versprechen statt, dank yvesmancera für die Ihren Laden von Daten

resortModule.factory('locaService', ['$http', '$rootScope', function ($http, $rootScope) { 
    var locationsPromise = null; 

    locaService.getLocations = 
     function() { 
      if (locationsPromise == null) { 
       locationsPromise = $http.get('/api/destinations').then(
        function(result) { 
         return result.data; 
        } 
       ); 
      } 

      return locationsPromise; 
     }; 

    ... 
} 

resortModule.controller('queryController',['$scope', 'locaService', function($scope, locaService) { 
    $scope.getLocations= locaService.getLocations().then(function(result) { 
     $scope.locations= result; 
    }); 
}]); 

Soweit der Beschleunigung, ich sehe nichts mit Ihrem Javascript falsch findet Fehler. Es könnte nur Ihr Api-Anruf sein, der viel Zeit in Anspruch nimmt. Wenn Sie Ihren HTML-Code veröffentlichen, könnten wir das überprüfen und sehen, ob etwas langsamer werden könnte.

+1

Ihr Code weist jedoch Fehler auf, bei nachfolgenden Aufrufen geben Sie keine Zusage mehr zurück, daher würde getLocations(). Dann fehlschlagen. – yvesmancera

+0

Ich mache eine Bearbeitung über^ –

+0

@allienx Ich denke, dass Ihr Code besser aussieht. Ich habe die HTML zur ursprünglichen Frage hinzugefügt. Ich benutze ein ng-repeat, also kann ich die Option "all" haben, die auf eine andere Seite umleitet. Sonst hätte ich die ng-Optionen benutzt. Nur damit du es weißt. –