角等待变量被定义
问题描述:
我有2个控制器和一个服务:角等待变量被定义
angular.module('objDescApp', ['ui.router', 'ui.bootstrap']);
angular.module('objDescApp').config(['$stateProvider', '$urlRouterProvider', '$httpProvider', function ($stateProvider, $urlRouterProvider, $httpProvider) {
'use strict';
$urlRouterProvider.otherwise('/');
$stateProvider
.state('object', {
url: '/{name}',
views: {
"body": {
controller: 'ObjectDetailCtrl',
template: '...'
}
});
angular.module('objDescApp').controller('ObjectListCtrl', function ($scope, $state, ConfigService) {
ConfigService.getConfig(function(){//get config from server
$scope.object = ConfigService.fillConfigForObjList(); //use config
}
}
angular.module('objDescApp').controller('ObjectDetailCtrl', ['$scope', '$stateParams', 'ConfigService', function ($scope, $stateParams, ConfigService) {
$scope.current_object = ConfigService.fillConfigForObjDetail(); //use config
}
angular.module('objDescApp').factory('ConfigService', function ($http, $rootScope) {
var jsonConf;
var confTemplate = {"sometemplate" : {}};
function fillConfigForObjList(){
... //use jsonConf variable , and always wait for init because of called only inside callback function of getConfig();
};
function fillConfigForObjDetail(){
... //use jsonConf variable , but doesnt wait for jsonConf initialization, so error var 'is undefined' here.So I need to add some waiting for 'jsonConf' initialization logic here
};
return {
jsonConf: jsonConf,
fillConfigForObjDetail: fillConfigForObjDetail,
fillConfigForObjList: fillConfigForObjList,
getConfig: function(callback){
$http({
method: 'GET',
url: endPointUrl,
transformResponse: undefined
}).then(
function successCallback(response) {
jsonConf = JSON.parse(response.data);
$rootScope.getConfigError = false;
callback();
},
function errorCallback(response) {
if(response.status == "404"){
jsonConf = confTemplate;
}else{
console.log("Get config error");
jsonConf = confTemplate;
$rootScope.getConfigError = true;
}
callback();
}
);
}
}
所以,当我加载页面与主路径“/”一切正常,因为“ObjectListCtrl”控制器触发器getConfig()函数响应后设置“jsonConf”可变,所以可以在任何状态之间naviagte和所有工作正常原因“jsonConf”已经设置好的;
但随着启动等路径状态“/ {名称}”如果我重新加载网页,因此“ObjectListCtrl”控制器trigers “getConfig()”请求到服务器,但在异步方式“ ObjectDetailCtrl”控制器被触发及其$ scope.current_object = ConfigService.fillConfigForObjDetail()表达,扔jsonConf is undefined error;
所以有人能告诉我,我怎么能等在内的‘fillConfigForObjDetail()’函数,直到‘jsonConf’由getConfig变量初始化()函数。
答
保存的承诺和链自许。
var jsonConfPromise;
function getConfig() {
//save httpPromise
jsonConfPromise = $http({
method: 'GET',
url: endPointUrl,
transformResponse: undefined
}).then(
function successCallback(response) {
jsonConf = JSON.parse(response.data);
$rootScope.getConfigError = false;
//return for chaining
return jsonConf;
},
function errorCallback(response) {
if(response.status == "404"){
jsonConf = confTemplate;
}else{
console.log("Get config error");
jsonConf = confTemplate;
$rootScope.getConfigError = true;
}
//return for chaining
return jsonConf;
}
);
//return promise
return jsonConfPromise;
};
你的功能有问题,可以再从承诺链。
function fillConfigForObjDetail(){
/*
... //use jsonConf variable , but doesnt wait for jsonConf
initialization, so error var 'is undefined' here.
So I need to add some waiting for 'jsonConf' initialization
logic here
*/
//chain from the promise
jsonConfPromise.then(function (jsonConf) {
//use resolved jsonConf
});
};
在你的控制器,而不是使用回调
此外,链从返回的承诺。
angular.module('objDescApp').controller('ObjectListCtrl', function ($scope, $state, ConfigService) {
var configPromise = ConfigService.getConfig();
configPromise.then(function() {
$scope.object = ConfigService.fillConfigForObjList();
});
});
的AngularJS框架使用承诺,而不是回调。
有关链接承诺的更多信息,请参阅AngularJS $q Service API Reference -- chaining promises。
因为调用承诺的
then
方法会返回一个新的派生承诺,所以很容易创建一个承诺链。它可以创建任何长度的链,并且自一个承诺可以与另一个承诺(这将进一步推迟其分辨率)来解决,所以能够暂停/在链中的任何点推迟承诺的分辨率。这使得实现强大的API成为可能。 1