ui路由器解析功能中的处理错误?(又名$stateChangeError)将数据传递到错误状态

Handling error in ui-routers resolve function? (aka $stateChangeError) Passing data to error state?

本文关键字:错误 stateChangeError 数据 状态 又名 路由器 功能 处理 ui      更新时间:2023-09-26

在我的Angular应用程序中,我通过ui-router处理路由/状态。如果一切正常 - 那就太好了。但是,处理resolve函数内部发生的错误的方法是什么?

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

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

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

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的方式去做。

我当前的解决方案使用$stateParams错误数据到我的error状态,但我必须为此使用 JSON 化的查询参数并获得一个非常丑陋的 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
  });
});

问题有没有其他方法可以将error对象传递到我的error状态而不会丑化我的 URL?(注意:我的error对象很复杂,而不仅仅是一个简单的字符串。

对我有用的策略是让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');
    }
});

您可以通过服务传递数据,您应该在错误控制器或错误状态的 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
});

希望这有帮助

您可以删除整个 url: 选项并将其替换为参数:选项。

                .state('error', {
                    abstract: false,
                    templateUrl: templateFor('error'),
                    controller: controllerFor('error'),
                    params: { 'error': 'An error has occurred' },
                    resolve: {
                        error: [
                            '$stateParams', function ($stateParams) {
                                return  $stateParams.error;
                            }
                        ]
                    }
                })

现在没有丑陋的网址。 并且控制器可以将错误作为参数获取。