2015-07-20 56 views
8

因此,我已经尝试了解服务和控制器的承诺。我宁愿在服务中解决它,以便我可以重复使用该变量而不必多次解决它。解决使用AngularJS的服务/工厂vs控制器的承诺

我遇到的问题是它的工作原理,但它非常缓慢地返回数据。所以我觉得我在这里做错了什么。我的ng选项需要大约5或6秒才能填充。哪个更好?我该如何改进我的代码,使其运行速度更快?

解决了服务:

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; 
    }); 
}]); 

解决在控制器:

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

[缓存承诺](http://stackoverflow.com/a/18745499/1048572)比缓存值要简单得多。 – Bergi

+0

@Bergi感谢您的链接。 – allienx

回答

4

在角度,服务是单身所以只有一个实例,在你的应用程序。这允许您解析数据(在您的服务中)一次,存储它,然后在随后的调用中只返回已解析的数据。这将允许您不要多次解析您的数据,并保持逻辑在服务和控制器之间分开。

UPDATE - 缓存的承诺相反,错误的感谢yvesmancera找到

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; 
    }); 
}]); 

至于加快你的加载数据,我看不出有什么毛病你的JavaScript。这可能只是你的api电话占用了很多时间。如果您发布与HTML相关的代码,我们可以检查一下,看看是否有什么东西可以放慢速度。

+1

虽然你的代码有错误,但在随后的调用中你不再返回一个promise,所以getLocations()会失败。 – yvesmancera

+0

我将在上面进行编辑^ –

+0

@allienx我认为你的代码看起来更好。我将html添加到原始问题中。我使用ng-repeat,这样我就可以拥有重定向到不同页面的'all'选项。否则,我会使用ng选项。只是让你知道。 –