工厂方法执行优先级似乎最高,因此回调没有数据可以处理。使这项工作的最佳方法是什么?
我有这种工厂
app.factory('jsonService', function($http) {
return {
getDistricts: function(callback) {
$http.get('data/districts.json').success(callback);
},
getLocations: function(path,callback) {
$http.get('data/'+path+'.json').success(callback);
}
};
});
和控制器
var app = angular.module('sandbox', []);
app.controller('sandboxCtrl',function ($scope,jsonService) {
//This one works
$scope.init1= function(){
jsonService.getDistricts(function(data){
$scope.districts = data;
$scope.currentDistrict = $scope.districts[0].name;
jsonService.getLocations($scope.currentDistrict,function(data){
$scope.locations1 = data;
})
});
};
$scope.init1();
//This one does not
$scope.init2= function(){
jsonService.getDistricts(function(data){
$scope.districts = data;
$scope.currentDistrict = $scope.districts[0].name;
})
jsonService.getLocations($scope.currentDistrict,function(data){
$scope.locations1 = data;
});
};
$scope.init2();
});
这是有效的plunker
答案 0 :(得分:1)
init1()
是这样做的正确方法。 init2()
确实有效,因为在jsonService.getLocations()
完成之前会调用jsonService.getDistritcs()
。角度$http
服务是异步的。由于jsonService.getLocations()
取决于jsonServicd.getDistricts()
的数据,因此您必须等到.getDistricts()
完成后才能调用.getLocations()
。一种方法是在.getLocations()
回调中调用.getDitricts()
,就像在init1()
中一样。
答案 1 :(得分:1)
Angular有一个名为$ q(documentation)的承诺的实现,您应该阅读。
由于http调用的异步性质,存在竞争条件。请查看下面链接的更新代码,其中显示了使用promises连续处理两个调用的代码运行(成功)的示例。
因此,在第一次通话成功后,由于承诺的力量,它将在不使用回调的情况下调用您的第二种服务方法。
jsonService.getDistricts()
.success(function(data) {
$scope.districts = data;
$scope.currentDistrict = $scope.districts[0].name;
jsonService.getLocations($scope.currentDistrict)
.success(function(locationData) {
$scope.locations = locationData;
})
});
承诺澄清:
基本承诺的原始实现使用then
来处理从$http
返回的响应和承诺,添加将从响应对象中解压缩数据的其他方法(success
,error
)如果您只是使用then
,则需要处理。