在我的Angular
应用程序中,我通过ui-router
处理路由/状态。如果一切正常 - 它很棒。但是什么是良好的方法来处理resolve
函数内发生的错误?
我目前的解决方案:
我有一个专用的error
州(类似于公共404.html
)。看起来像这样:
// inside config()
.state('error', {
url: '/error',
controller: 'ErrorCtrl',
templateUrl: 'error.html' // displays an error message
})
如果resolve
内发生错误,我会通过m $stateChangeError
函数中的广播run
抓住它:
angular.module('myModule').run(function($state) {
$rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error) {
event.preventDefault();
$state.go('error');
});
});
这有效,但我想根据错误更改'error.html'
内的错误消息。我不想污染$rootScope
,我希望以ui-router
&#es;方式进行污染。
我当前的解决方案使用$stateParams
将错误数据导入我的error
状态,但我必须使用JSONified查询参数来获取一个非常难看的网址:
// inside config()
.state('error', {
url: '/error?data&status&config', // accept these three params
controller: 'ErrorCtrl',
templateUrl: 'error.html' // displays an error message
})
angular.module('myModule').run(function($state) {
$rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error) {
event.preventDefault();
$state.go('error', JSON.stringify(error)); // error has data, status and config properties
});
});
问题
我是否可以通过不同的方式将error
对象传递给error
状态,而无需更新我的网址? (注意:我的error
对象很复杂,而不仅仅是一个简单的字符串。)
答案 0 :(得分:25)
您可以通过服务传递数据,您应该在错误控制器或onEnter错误状态方法中访问该数据。
或者你可以"丰富"你的错误状态。也许它不是有角度的方式,但我的意思是:
$rootScope.$on('$stateChangeError', function (event, toState, toParams, fromState, fromParams, error) {
event.preventDefault();
$state.get('error').error = { code: 123, description: 'Exception stack trace' }
return $state.go('error');
});
在错误状态配置中:
.state('error', {
url: 'error',
resolve: {
errorObj: [function () {
return this.self.error;
}]
},
controller: 'ErrorCtrl',
templateUrl: 'error.html' // displays an error message
});
希望这有帮助
答案 1 :(得分:25)
对我有用的策略是让resolve
函数使用错误对象返回被拒绝的承诺:
$stateProvider.state('needs_authentication', {
url: '/auth',
resolve: {
user: function ($q, authService) {
if (authService.isAuthenticated()) {
...
}
else {
var errorObject = { code: 'NOT_AUTHENTICATED' };
return $q.reject(errorObject);
}
}
}
});
这使您的$stateChangeError
函数能够处理特定的错误条件:
$rootScope.$on('$stateChangeError', function (evt, toState, toParams, fromState, fromParams, error) {
if (angular.isObject(error) && angular.isString(error.code)) {
switch (error.code) {
case 'NOT_AUTHENTICATED':
// go to the login page
$state.go('login');
break;
default:
// set the error object on the error state and go there
$state.get('error').error = error;
$state.go('error');
}
}
else {
// unexpected error
$state.go('error');
}
});
答案 2 :(得分:4)
您可以删除整个网址:选项并将其替换为只有params:选项。
.state('error', { abstract: false, templateUrl: templateFor('error'), controller: controllerFor('error'), params: { 'error': 'An error has occurred' }, resolve: { error: [ '$stateParams', function ($stateParams) { return $stateParams.error; } ] } })
现在没有丑陋的网址。并且控制器可以将错误作为参数。