我有一个带有服务的应用程序,该服务包装了我的API调用:
var ConcernService = { ... get: function (items_url, objId) { var defer = $q.defer(); $http({method: 'GET', url: api_url + items_url + objId}). success(function (data, status, headers, config) { defer.resolve(data); }).error(function (data, status, headers, config) { console.log('ConcernService.get status',status); defer.reject(status); }); return defer.promise; },
并且我正在使用UI-Router在状态之间进行转换:
concernsApp .config( function ($stateProvider, $urlRouterProvider) { $urlRouterProvider.otherwise("/404/"); $stateProvider.state('project', { url: '/project/:projectId/', resolve: { project: function ($stateParams, ConcernService) { return ConcernService.get('projects/', $stateParams.projectId); }, }, views: { ... } });
我不再使用普通的AngularJS路由器,并且难以理解如何实现404。我可以看到ConcernService抛出console.log状态被拒绝,但是如何在状态路由器中捕获它呢?
ConcernService
console.log
otherwise()仅当没有其他 路由 匹配时才调用该规则。您真正想要的是拦截$stateChangeError事件,即在状态转换中出现问题(例如,解析失败)时触发的事件。您可以在状态更改事件文档中阅读有关此内容的更多信息。
otherwise()
$stateChangeError
您要执行的操作的最简单实现是这样的:
$rootScope.$on('$stateChangeError', function(event) { $state.go('404'); });
同样,由于$http它本身是基于promise(可resolve解析)构建的,因此您的ConcernService方法可以简化为单一格式(我知道您是出于调试目的而对其进行扩展的,但是可以像FYI一样轻松地将其链接起来):
$http
resolve
var ConcernService = { get: function (items_url, objId) { return $http.get(api_url + items_url + objId); } }