0

我正在尝试在控制器开始运行之前初始化我的应用程序服务。

我原以为我可以通过首先解决一个承诺返回函数来实现这一点:

va.config(['$routeProvider', function($routeProvider) {
$routeProvider.
    when('/', {templateUrl: '../partials/home.php',   controller: 'VaCtrl',resolve: {
        pp: vac.loadData
    }});
}]);


var  vac = va.controller('VaCtrl',function($scope,$http,$q,packingProvider){
    console.dir(packingProvider.data[2]); 
});


vac.loadData = function($http,$timeout,$q,packingProvider){

   $http.post('../sys/core/fetchPacking.php').then(function(promise){
        packingProvider.data = promise.data;

    });

    var defer = $q.defer();
    $timeout(function(){
        defer.resolve();
    },2000);
    return defer.promise;
};

然而,在promise被解决之前,控制器仍然被加载,导致控制台大喊大叫

无法读取未定义的属性“2”

对我。

我究竟做错了什么?

编辑:

此外,控制器似乎被调用了两次,第一次使用未定义的 pacingProvider.data 对象,2 秒后一切正常。

4

2 回答 2

3

注意:虽然这会解决您的问题,但这个答案可能是正确的解决方案。

服务总是在控制器之前初始化。正如您所说,问题在于您的承诺尚未实现。最好的选择是坚守承诺。

不要暴露data对象,而是暴露 Promise 并使用它:

vac.loadData = function($http,$timeout,$q,packingProvider){
  packingProvider.data = $http.post('../sys/core/fetchPacking.php');
  return packingProvider.data;
};

在您的控制器中,始终附加到承诺,在第一次解决之后,它将在下一个滴答声中得到解决:

var  vac = va.controller('VaCtrl',function($scope,$http,$q,packingProvider){
  packingProvider.data.then(function(value) {
    console.dir(value[2]);
  }); 
});
于 2013-10-10T14:56:55.340 回答
3

您可以直接使用promise返回的,而不是使用 返回的。$timeoutpromise$http

用这种方式重写你的loadDatafn -

vac.loadData = function($http,$timeout,$q,packingProvider){

    var promise = $http.post('../sys/core/fetchPacking.php').then(function(promise){
        packingProvider.data = promise.data;
    });

    return promise;
};

在此处阅读该General Usage部分的第一行 - $http promise

另外,resolve是一个依赖关系图

resolve - {Object.=} - 一个可选的依赖关系映射,应该注入到控制器中。如果这些依赖项中的任何一个是承诺,路由器将等待它们全部解决或在控制器实例化之前被拒绝。

因此,Angular 将自动公开映射以进行注入。所以,你可以这样做 -

var vac = va.controller('VaCtrl', function($scope, pp){
  // 'pp' is the name of the value in the resolve map for $routeProvider.
  console.dir(pp[2]);
});
于 2013-10-10T15:00:29.990 回答