AngularJS UI路由器处理404s

时间:2014-04-24 22:58:59

标签: angularjs angular-ui-router

我有一个应用程序,其中包含我的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路由器,而且我很难理解如何实现404s。我可以看到ConcernServiceconsole.log状态拒绝,但我如何在状态路由器中捕获它?

6 个答案:

答案 0 :(得分:22)

仅当没有其他路由匹配时才会调用otherwise()规则。你真正想要的是拦截$stateChangeError事件,这是在状态转换中出现问题时被触发的事件(例如,解决失败)。您可以在state change event docs

中详细了解相关内容

您尝试做的最简单的实现将是这样的:

$rootScope.$on('$stateChangeError', function(event) {
  $state.go('404');
});

此外,由于$http本身是基于promises(resolve解析)构建的,因此您的ConcernService方法可以简化为单行(我意识到您将其扩展为调试目的,但你可以很容易地链接它,只是FYI):

var ConcernService = {

  get: function (items_url, objId) {
    return $http.get(api_url + items_url + objId);
  }
}

答案 1 :(得分:7)

我在两个404州之间存在差异:

服务器

  • 显示404页面,具体取决于服务器响应HTTP Code 404
  • 定义网址非常重要,这样用户就可以停留在发生错误的网址上

<强>客户端

  • angular ui路由器找不到URL(没有定义的URL)

Angular UI-Router状态代码:

$stateProvider
  .state('404server', {
    templateUrl: '/views/layouts/404.html'
  })
  .state('404client', {
    url: '*path',
    templateUrl: '/views/layouts/404.html'
  });

$httpProvider拦截器中的代码:

if(response.status === 404) {
  $injector.get('$state').go('404server');
}

我使用$injector代替$state的原因解释为here

答案 2 :(得分:3)

你也可以试试这样的东西,看看它是否适合你。您可能需要根据自己的需要进行调整:

.state('otherwise', {
    abstract: true,
    templateUrl: 'views/404.html'
})
.state('otherwise.404', {
    url: '*path',
    templateUrl: 'views/404.html'
})

答案 3 :(得分:2)

$ urlRouterProvider只能像$ watch到$ location一样工作,如果实际的URL与.config()函数中定义的规则之一匹配,那么它将重定向到指定的路由。

这是我的建议,定义&#34; / 404 /&#34;作为一个州:

$stateProvider.state('404', {
  url:'/404/',
  views:{
      ...
  }
});

在reject()函数内部移动到404状态

 if(status == '404'){
   $state.transitionTo('404');
 }

您必须添加ui-router作为项目模块的依赖项,并使用控制器中的$ state provider以便能够使用$ state.transitionTo()

以下是一些信息:https://github.com/angular-ui/ui-router/wiki/Quick-Reference#statetransitiontoto-toparams--options

答案 4 :(得分:1)

我设法在不使用$urlRoutProvider的情况下处理404,因为我只是通过测试$state.transistion来使用状态:

angular.module("app", []).run(["$state", "$rootScope", function($state, $rootScope) => {
    $rootScope.$on("$locationChangeSuccess", function() {
        if (!$state.transition) {
            $state.go("404");
        }
    });
}]);

答案 5 :(得分:0)

Data Source=localhost\SQLEXPRESS; …

$urlRouterProvider.otherwise('/page-not-found');

将处理您的页面未找到问题。

如果你想提出有目的地使用状态或网址的404。如果您想执行任何操作,我们已经创建了一个单独的控制器。