【问题标题】:Resolving a promise in a service/factory vs in a controller with AngularJS使用 AngularJS 解决服务/工厂与控制器中的承诺
【发布时间】:2015-10-09 20:58:07
【问题描述】:

所以我一直在尝试在服务和控制器中获得解决的承诺。我更愿意在服务中解决它,这样我就可以重用变量而不必多次解析它。

我遇到的问题是它可以工作,但是它返回数据的速度非常非常慢。所以我觉得我在这里做错了什么。填充我的 ng-options 大约需要 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>

【问题讨论】:

标签: javascript angularjs angular-promise angular-services


【解决方案1】:

在 Angular 中,服务是单例的,因此您的应用中只有一个实例。这允许您解析一次数据(在您的服务中),存储它,然后在后续调用中返回已经解析的数据。这将允许您不必多次解析数据,并让您的逻辑在服务和控制器之间保持分离。

更新 - 改为缓存承诺,感谢 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 相关的代码,我们可以检查一下,看看是否有任何东西会减慢它的速度。

【讨论】:

  • 你的代码有错误,在随后的调用中你不再返回一个承诺,所以 getLocations().then 会失败。
  • @alienx 我确实认为您的代码看起来更好。我将 html 添加到原始问题中。我使用了 ng-repeat,因此我可以使用“全部”选项重定向到不同的页面。否则我会使用 ng-options。让您知道。
  • @BrookeClonts ng-options 确实提供了 speed optimizations 而不是 ng-repeat 所以这可能会导致延迟
  • 好的,我会用 ng-options 试试。如果它会延迟页面那么大,那么使用“全部”选项是不值得的。非常感谢!你们是最棒的。抱歉,我边走边学。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-02
  • 1970-01-01
  • 2017-03-23
  • 1970-01-01
  • 2017-01-30
  • 1970-01-01
  • 2013-08-09
相关资源
最近更新 更多