AngularJs控制器,等待服务$ http结果

时间:2014-10-17 12:33:53

标签: angularjs http angular-promise

我想在控制器完成其余工作之前等待服务$ http结果。 我为myData测试了一些硬编码的JSON,它在控制器中可见,但是当我尝试用$ http请求填充myData时,控制器不会等待它,只是走过剩下的代码。 Chrome webdevelopper中的网络标签显示了请求的预期结果。

我已经拥有以下内容:

var ListerApp = angular.module('ListerApp',[
    'ListerAppFilters',
    'sharedFactoryApp',
    'sharedServiceApp',
    'ListerAppController',
    'infinite-scroll',
    'angular-inview',
    'ngRoute'
]);

ListerApp.config(['$routeProvider', '$httpProvider', function($routeProvider, $locationProvider) {
    $routeProvider
        .when('/list',
            {
                templateUrl: '/assets/services/partials/list.html',
                controller: 'ListerCtrl',
                resolve : {
                    'sharedServiceAppData': function($sharedServices){
                        // sharedFactoryAppData will also be injectable in your controller, if you don't want this you could create a new promise with the $q service
                        return $sharedServices.promise();
                    }
                }
            }
        );
}]);

angular.module('sharedServiceApp', []).service('$sharedServices', ['$http', '$rootScope', '$q', function($http, $rootScope, $q) {
    var myData = null;

   return {
        promise : function () {
            if (!myData) {
                $http({method : 'GET', url : '/shop/api/json', params : {
                        end         : $rootScope.endmarkerSyncDataset,
                        page        : 1,
                        per_page    : $rootScope.itemsPerPage
                    }
                }).success(function (data) {
                    myData = data.data_set;
                    //deferred.resolve(data.data_set);
                });

                // I allready tested this and this is OK: myData = {foo : 'bar'};
            }
        },
        getShopData: function () {
            return myData;
        }
    };
}]);

(function(){
    var appController = angular.module('ListerAppController', []);

    appController.controller('ListerCtrl', ['$scope', '$rootScope', '$http', '$filter', '$timeout', '$sharedFactories', '$sharedServices',
        function($scope, $rootScope, $http, $filter, $timeout, $sharedFactories, $sharedServices) {
            $scope.items = $sharedServices.getShopData();
            console.log($scope.items); // return myData -> null
        }
})();

2 个答案:

答案 0 :(得分:3)

我已经做了很多次这就是我通常在 routeProvider 的解析对象中做的事情,需要确保你适当地返回所有的promises以便路由更改等待解决属性。

 $routeProvider
    .when('/path',
        {
            templateUrl: 'some/path/to/template.html',
            controller: 'myCtrl',
            resolve : {
                'myData': ['mySrvc',function(mySrvc){
                    return mySrvc.someMethod().then(function(response){
                        return response.data;
                    },function(){
                        return {};
                    });
                }]
            }
        }
    );

然后服务:

angular.module('myApp.services').factory('mySrvc',['$http',function($http){
    var _url = 'https://someurl.com/path/to/api';

    return {
        someMethod : function(vars){
            if(angular.isDefined(vars)){
                return $http.post(_url,$.param(vars),{headers:{'Content-Type':'application/x-www.form-urlencoded'}});
            }else{
                return $http.get(_url);
            }
        }
    };
}]);

然后在控制器中,您需要在控制器的参数列表末尾注入resolve参数。

angular.module('myApp.controllers').controller('myCtrl',['$scope','myData',function($scope,myData){

});

在您的代码中,在 routeProvider 解析对象中,您从一个不返回任何内容的函数返回,请尝试从$http返回承诺然后是服务成功函数中的data.data_set值。

答案 1 :(得分:0)

我找到了类似$ q.defer,解决和承诺的东西。 它保留了所有东西,直到状态"承诺"到了。

此处a link

angular.module('sharedServiceApp', []).service('$sharedServices', ['$http', '$rootScope', '$q', function($http, $rootScope, $q) {
    var myData = null;

    return {
        promise : function () {
            if (!myData) {
               var deferred = $q.defer();
               $http({method : 'GET', url : '/shop/api/json', params : {
                    end         : $rootScope.endmarkerSyncDataset,
                    page        : 1,
                    per_page    : $rootScope.itemsPerPage
                }
            }).success(function (data) {
                myData = data.data_set;
                deferred.resolve(data.data_set);
            }).error(function(data, status, headers, config) {
                deferred.reject("Error: request returned status " + status); 
            });
            return deferred.promise;
        } else {
            return myData;
        }
    },
    getShopData: function () {
        return myData;
    },
    setShopData: function (data) {
        myData= data;
    }
};

}]);