2013-10-11 54 views
35

我已經在Angular中編寫了一個Web應用程序的一部分。爲了確保覆蓋所有路由,我想將redirectTo屬性添加到$routeProvider,以便將無效路由返回到不使用Angular的Web應用程序的根目錄。

我想:

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

但很明顯,在URL的角度控制部分這隻路線,所以用戶會被重定向到像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世界移動得太快一樣,以前的答案可能不再是這種情況。

+2

可能在服務器端處理它。 – tymeJV

+2

我也在尋求解決這個問題。我正在將我的應用程序切換到Angular,並且仍然有部分仍然來自服務器。需要找到一種方法來連接角部分和非角部分 – Michael

回答

41

上面的解決方案/ 404不適合我。 這似乎工作

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

PS。我正在使用Angular 1.2.10

+4

我也使用Angular 1.2,並且接受的答案沒有工作,但是這個做了。該模板也是必要的。 – Chadwick

+0

如果您需要導航到其他地方而不是您的域的根目錄,則可能需要使用散列'#',因爲使用'window.location'方法,所以會削減'/'和/或一些'a'錨點名稱。 –

19

你可以做這樣的事情:

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

它實質上是一樣的,只是它使用較少的代碼。

+1

我沒有意識到控制器可以像這樣內聯。這非常酷,謝謝! – surfitscrollit

18

不確定Angular JS的版本是否被接受,但'redirectTo'屬性接受函數。那麼,爲什麼不做這樣簡單的事情呢:

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

顯然,你必須創建自己的404.html。或者你的404頁面在哪裏。

+1

如何將當前路徑傳遞給redirectTo函數? –

+0

您可以通過'document.URL'獲取當前網址在JavaScript中。 – stack247

+0

document.location.pathname可能是獲取路徑的最佳選擇 –

5

沒有答案,包括標記的答案爲我工作。我相信我的解決方案也可以解決您的問題,我也會分享我的使用案例以供將來的讀者參考。

問題與使用路由控制器方法: 當控制器加載路由已經訪問的歷史記錄API狀態對我來說(我用HTML5模式,不知道這是否會影響非HTML5模式)。

因此,儘管我可以使用window.location將人員轉發到正確的頁面。替換('/');,;如果用戶在瀏覽器中點擊「返回」,則進入無效狀態。

場景:我們實現了多頁模型,我的管理頁面模塊與我的主頁(非管理)模塊分開。我在我的一個管理控制器中有一個$ location.path('/'),但是因爲主頁沒有打包到管理頁面模塊中,所以當我檢測到'/'路由時,我想強制整頁重新加載。

解決方案: 我們在$ routeChangeStart攔截ngRoute訪問任何狀態信息之前。通過這種方式,我們甚至可以通過鏈接直接redirectTo PARAM在$路徑

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; 
     }); 
     } 
    }); 
    } 
]); 

請提供任何反饋,我會使用此代碼自己指定的外部HREF。 乾杯

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

1

嗨,即使它已經兩年了,只是有一個人誰尋求這個答案,只需使用window.location.assign(「/登錄」)。這對我有用。

+0

聽起來不錯 - 我只是查找'location.assign'和'location.replace'之間的區別,並找到了一個很好的答案,如果有人感興趣:http://stackoverflow.com /問題/ 4505798 /差之間窗口定位指派和 - 窗位置的替換 – surfitscrollit