2014-10-08 43 views
1

执行的看来,工厂方法执行优先级是最高的,因此回调没有数据来处理。做这项工作的最佳方式是什么?

我得到了这样的工厂

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

回答

1

角有一个名为$ Q()承诺的实现,你应该在阅读起来。

有一种竞争状态,由于HTTP调用的异步性质。请查看下面链接的更新代码,该代码显示了您的代码正在运行(成功)使用承诺来连续处理您的两个调用的示例。所以,在你的第一个成功

调用它会调用你的第二个服务方法都不用感谢回调承诺的力量。

jsonService.getDistricts() 
    .success(function(data) { 
    $scope.districts = data; 
    $scope.currentDistrict = $scope.districts[0].name; 
    jsonService.getLocations($scope.currentDistrict) 
     .success(function(locationData) { 
     $scope.locations = locationData; 
     }) 
    }); 

updated PLKR

承诺澄清: 原始实施基本承诺使用then来处理响应和承诺从$http返回添加其他方法(successerror)将从响应对象解压您的数据你需要处理,如果你只是使用then

+1

+1 OP:我认为你应该接受这个答案,它比我的好得多。然而,看看我在答案中给出的例子,它们可能是这个例子的一个很好的补充。 – Josep 2014-10-08 14:09:54

+0

另外,请注意,打开服务中的承诺并不是一个好主意,因为这增加了不必要的耦合到您的工厂。 – Josep 2014-10-08 14:14:09

+0

非常感谢这些信息。但是,我仍然可以使用这种方法在分离函数中调用.getLocations,还是必须将它绑定到.success()或.then()方法? – 2014-10-08 14:28:23

1

init1()是这样做的正确方法。 init2()确实有效,因为在jsonService.getDistritcs()完成之前jsonService.getLocations()正在调用。角度$http服务是异步的。由于jsonService.getLocations()依赖于从jsonServicd.getDistricts()数据,你必须等待,直到.getDistricts()调用.getLocations()之前完成。要做到这一点的方法之一是在.getDitricts()回调中调用.getLocations(),就像你在init1()一样。

+0

init1()是这样做的正确方法吗?我不同意,我认为服务应该返回承诺而不是解开它们。 – Josep 2014-10-08 14:15:15

+0

有多种方法可以做到这一点。当我说'init1()'是这样做的正确方法时,我的意思是与'init2()'相比。他是否想要使用回调或承诺是他的选择。 – JME 2014-10-08 14:20:42

+0

我并不是说你的回答是错误的,因为它不是,实际上你指出$ http服务的调用是异步的,因此如果你想要使用由其中一个,你将不得不等待,直到数据回来...所以,+1。然而我认为问题的根源在于OP不知道承诺如何在角度上工作。 – Josep 2014-10-08 14:34:37