我正在尝试在控制器开始运行之前初始化我的应用程序服务。
我原本以为我可以通过先解决一个承诺返回函数来实现这个目的:
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,一切都很好。
答案 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
此外,resolve
是map 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]);
});