ui-routers解决功能中的处理错误?(又名$ stateChangeError)将数据传递给错误状态?

Pip*_*ipo 29 javascript angularjs angular-ui-router

在我的Angular应用程序中,我通过处理路由/状态ui-router.如果一切正常 - 它很棒.但是,处理函数内部错误的方法是什么resolve

我目前的解决方案:我有一个专用error状态(类似于常见状态404.html).看起来像这样:

// inside config()
.state('error', {
  url: '/error',
  controller: 'ErrorCtrl',
  templateUrl: 'error.html' // displays an error message
})
Run Code Online (Sandbox Code Playgroud)

如果在resolve我内部发生错误,我通过广播$stateChangeError的m run函数捕获它:

angular.module('myModule').run(function($state) {
  $rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error) {
    event.preventDefault();
    $state.go('error');
  });
});
Run Code Online (Sandbox Code Playgroud)

这有效,我想在我的'error.html'依赖于错误的内部更改我的错误消息.我不想污染它$rootScope,我想以ui-router'esk方式做到这一点.

我当前的解决方案使用$stateParams错误数据到我的error状态,但我必须使用JSONified查询参数,并得到一个非常丑陋的URL:

// 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
  });
});
Run Code Online (Sandbox Code Playgroud)

问题 我是否可以通过不同的方式将error对象传递到我的error状态而不会更改我的URL?(注意:我的error对象很复杂,而不仅仅是一个简单的字符串.)

wil*_*ver 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');
});
Run Code Online (Sandbox Code Playgroud)

并在你的错误状态配置:

.state('error', {
    url: 'error',
    resolve: {
        errorObj: [function () {
            return this.self.error;
        }]
    },
    controller: 'ErrorCtrl',
    templateUrl: 'error.html' // displays an error message
});
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助


Mil*_*ler 25

对我resolve有用的策略是让函数返回带有错误对象的被拒绝的promise :

$stateProvider.state('needs_authentication', {
    url: '/auth',
    resolve: {
        user: function ($q, authService) {
            if (authService.isAuthenticated()) {
                ...
            }
            else {
                var errorObject = { code: 'NOT_AUTHENTICATED' };
                return $q.reject(errorObject);
            }
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

这使您的$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');
    }
});
Run Code Online (Sandbox Code Playgroud)