我想在控制器完成其余工作之前等待服务$ 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
}
})();
答案 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;
}
};
}]);