AngularJS - 在控制器之前初始化服务

时间:2013-10-10 14:43:28

标签: javascript angularjs

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

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

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;
};

但是,在承诺已经解决之前,控制器仍然被加载,导致控制台大喊大叫

  

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

对我说。

我做错了什么?

修改

此外,控制器似乎被调用两次,第一次使用未定义的pacingProvider.data对象,稍后有两个secons,一切都很好。

2 个答案:

答案 0 :(得分:3)

注意:虽然这可以解决您的问题,this answer可能是正确的解决方案。

服务器始终在控制器之前初始化。正如你所说,问题在于你的承诺尚未产生。最好的选择就是坚持承诺。

不是暴露data对象,而是公开承诺并使用它:

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]);
  }); 
});

答案 1 :(得分:3)

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

以这种方式重写loadData fn -

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

此外,resolvemap of dependencies

  

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

因此,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]);
});