【问题标题】:Using $routeProvider to redirect to routes outside of Angular使用 $routeProvider 重定向到 Angular 之外的路由
【发布时间】:2013-10-19 17:56:49
【问题描述】:

我已经用 Angular 编写了 Web 应用程序的一部分。为了确保覆盖所有路由,我想在$routeProvider 中添加一个redirectTo 属性,以便将无效路由返回到不使用Angular 的Web 应用程序的根目录。

我试过了:

$routeProvider.otherwise({
    redirectTo: '/'
});

但显然这只路由在 URL 的 Angular 控制部分中,因此用户将被重定向到像 http://app.com/angular-part-of-web-app# 这样的 URL,而不是我希望他们去的 http://app.com

我已经解决了这个问题,将一个空白部分用作“404”页面,然后使用一个仅使用 $window 对象重定向到所需页面的控制器:

routes.js

// Redirect to site list.
$routeProvider.when('/404', {
    templateUrl: '/partials/404.html',
    controller: 'RedirectCtrl'
});

// Redirect to the 404 page.
$routeProvider.otherwise({
    redirectTo: '/404'
});

controllers.js

// Controller to redirect users to root page of site.
.controller('RedirectCtrl', ['$scope', '$window', function ($scope, $window) {

    $window.location.href = '/';
}]);

但是,这已经敲响了“太老套,必须是更好的方法”的警钟。在 Angular 中有没有更好的方法来做到这一点?

编辑:Angular routes - redirecting to an external site? 没有给出相同问题的答案。我将保留我的问题,而不是将其标记为重复(现在),因为 Angular 世界发展如此之快,以前的答案可能不再是这种情况。

【问题讨论】:

  • 可能在服务器端处理它。
  • 我也想解决这个问题。我正在将我的应用程序切换到 Angular 并且有一些仍然从服务器提供的部分。需要找到一种方法来连接 Angular 部分和非 Angular 部分

标签: javascript angularjs


【解决方案1】:

你可以这样做:

$routeProvider.when('/404', {
    controller: ['$location', function($location){
        $location.replace('/');
    }]
}).otherwise({
    redirectTo: '/404'
});

本质上是一样的,只是它使用的代码更少。

【讨论】:

  • 我没有意识到控制器可以这样声明为内联。太好了,谢谢!
【解决方案2】:

上面的 /404 解决方案对我不起作用。 然而,这似乎有效

.otherwise({
    controller : function(){
        window.location.replace('/');
    }, 
    template : "<div></div>"
});

PS。我正在使用 Angular 1.2.10

【讨论】:

  • 我也在使用 Angular 1.2 并且接受的答案不起作用,但这个答案起作用了。模板也是必要的。
  • 如果您需要导航到其他地方而不是域的根目录,您可能需要散列 # ,斜线 / 和/或一些 a 锚名称,因为使用了 window.location 方法.
【解决方案3】:

不确定接受的答案是在哪个版本的 Angular JS 上编写的,但 'redirectTo' 属性包含一个函数。那么,为什么不做一些像这样更简单的事情:

$routeProvider.otherwise({
    redirectTo: function() {
        window.location = "/404.html";
    }
});

显然,您必须创建自己的 404.html。或者您的 404 页面在哪里。

【讨论】:

  • 如何将当前路径传递给redirectTo函数?
  • 你可以通过document.URL获取JavaScript中的当前URL
  • document.location.pathname 可能是获取路径的最佳选择
  • window.location.replace 更简洁,因为它替换了浏览器历史记录中的错误 url 并防止任何后退按钮循环 c**p
【解决方案4】:

包括标记答案在内的所有答案都不适合我。我相信我的解决方案也可以解决您的问题,我也会分享我的用例以供将来的读者参考。

使用路由控制器方法的问题: 加载控制器时,路由已经为我访问了 History API 状态(我使用 HTML5 模式,不确定这是否会影响非 HTML5 模式)。

因此,即使我可以使用 window.location.replace('/');, 如果用户随后在其浏览器上单击返回,它将进入无效状态。

场景:我们实现了多页面模型,我的管理页面模块与我的主页(非管理)模块分开。我的一个管理控制器中有一个 $location.path('/') ,但由于主页未打包到管理页面模块中,我想在检测到“/”路由时强制重新加载整个页面。

解决方案: 在 ngRoute 访问任何状态信息之前,我们必须在 $routeChangeStart 处进行拦截。这样我们甚至可以通过将 url 传递给 $route 中的 redirectTo 参数来指定外部 href

angular.module('app',['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
  $routeProvider
  .when('/admin/default', {template: somePageTemplate})
  /*
   *  More admin-related routes here...
   */
  .when('/',{redirectTo:'/homepage'})  // <-- We want to intercept this
  .otherwise({redirectTo: '/admin/default'}); 
}])
.controller('MainCtrl',[ // <- Use this controller outside of the ng-view!
  '$rootScope','$window',
  function($rootScope,$window){
    $rootScope.$on("$routeChangeStart", function (event, next, current) {
      // next <- might not be set when first load
      // next.$$route <- might not be set when routed through 'otherwise'
      // You can use regex to match if you have more complexed path...
      if (next && next.$$route && next.$$route.originalPath === '/') {
        // Stops the ngRoute to proceed
        event.preventDefault();
        // We have to do it async so that the route callback 
        // can be cleanly completed first, so $timeout works too
        $rootScope.$evalAsync(function() {
          // next.$$route.redirectTo would equal be '/homepage'
          $window.location.href = next.$$route.redirectTo;
        });
      }
    });
  }
]);

请提供任何反馈,因为我将自己使用此代码。 干杯

参考: https://github.com/angular/angular.js/issues/9607

【讨论】:

    【解决方案5】:

    嗨,尽管已经两年了,但对于搜索此答案的人来说,只需使用 window.location.assign('/login')。这对我有用。

    【讨论】:

    • 听起来不错 - 我刚刚查找了 location.assignlocation.replace 之间的区别并找到了一个很好的答案,如果有人感兴趣的话:stackoverflow.com/questions/4505798/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-10
    • 2016-03-05
    • 2018-04-18
    • 1970-01-01
    • 1970-01-01
    • 2018-12-27
    • 2017-07-27
    相关资源
    最近更新 更多