2013-09-25 27 views
34

Tôi đang làm việc trên ứng dụng AngularJS có tất cả tuyến đường (ví dụ: .when('/:slug', {...)) cần thiết để hỗ trợ định dạng url cũ từ phiên bản trước đó (không góc cạnh) của ứng dụng. Bộ điều khiển đáp ứng với bắt tất cả các cố gắng kéo một đối tượng liên quan, và, nếu không tìm thấy, chuyển hướng đến một trang 404 bằng cách sử dụng phương pháp $location.path. Điều này làm việc để đưa người dùng đến trang 404, nhưng khi người dùng truy cập lại trong trình duyệt của họ, họ sẽ đưa họ trở lại trang đã buộc họ vào trang 404 ở nơi đầu tiên và cuối cùng họ không thể thoát khỏi chu kỳ.AngularJS chuyển hướng mà không cần đẩy trạng thái lịch sử

Câu hỏi của tôi là nếu có 1) mẫu tốt hơn để xử lý tình huống này hoặc 2) nếu có cách để định tuyến lại người dùng không buộc trạng thái đẩy lịch sử trong trình duyệt?

Trả lời

56

Bạn có thể thay đổi url mà không cần thêm vào trạng thái lịch sử, được tìm thấy here trong "Phương thức thay thế". Điều này có hiệu quả giống như gọi history.replaceState của HTML5().

$location.path('/someNewPath').replace(); 

Tôi không thể thay đổi chế độ xem mà không thay đổi url. Phương pháp duy nhất để thay đổi chế độ xem mà tôi đã tìm thấy là thay đổi đường dẫn vị trí.

+0

Bạn đang nói bằng cách sử dụng phương pháp thay thế, bạn có thể cập nhật URL mà không thay đổi trạng thái khác trên trang? Ý tôi là về hiệu ứng thuần túy của việc thay đổi URL? Bởi vì đây là những gì cho phép khả năng các trang là lớp phủ (với các Url đúng) tương tự như sở thích. – CMCDragonkai

+0

Tôi đã viết rằng một thời gian trước nhưng tôi nghĩ rằng sự thay đổi url vẫn kích hoạt sự kiện góc để định tuyến lại nhưng điều này sẽ giữ cho nó hiển thị trong lịch sử trình duyệt vì vậy ít nhất nút quay lại của bạn vẫn hoạt động. – thrashr888

+3

Đẹp. Nó cũng hoạt động với '.search()' – vtortola

3

Hoạt động bình thường của hệ thống tuyến đường là dành cho dịch vụ $route để xem sự kiện $locationChangeSuccess và sau đó bắt đầu tải tuyến đường. Khi nó được thực hiện tải mẫu, thực hiện các bước giải quyết và instantiating bộ điều khiển nó sau đó lần lượt phát sóng một sự kiện $routeChangeSuccess. Điều đó $routeChangeSuccess được theo dõi bởi chỉ thị ng-view, và đó là cách nó biết để trao đổi ra các mẫu và phạm vi khi tuyến đường mới đã sẵn sàng.

Với tất cả những điều trên đã nói, nó có thể làm việc để có mã ứng dụng bắt chước hành vi của các dịch vụ $route bằng cách cập nhật các tuyến đường hiện tại và phát ra sự kiện thay đổi lộ trình để có được cái nhìn để cập nhật:

var errorRoute = $route.routes[null]; // assuming the "otherwise" route is the 404 
// a route instance is an object that inherits from the route and adds 
// new properties representing the routeParams and locals. 
var errorRouteInstance = angular.inherit(
    errorRoute, 
    { 
     params: {}, 
     pathParams: {}, 
    } 
); 
// The $route service depends on this being set so it can recover the route 
// for a given route instance. 
errorRouteInstance.$$route = errorRoute; 

var last = $route.current; 
$route.current = errorRouteInstance; 

// the ng-view code doesn't actually care about the parameters here, 
// since it goes straight to $route.current, but we should include 
// them anyway since other code might be listening for this event 
// and depending on these params to behave as documented. 
$rootScope.broadcast('$routeChangeSuccess', errorRoute, last); 

Ở trên giả định rằng tuyến đường "khác" của bạn không có bất kỳ bước "giải quyết" nào. Nó cũng giả định rằng nó không mong đợi bất kỳ $routeParams, đó là tất nhiên đúng cho các tuyến đường "nếu không" nhưng có thể không đúng nếu bạn sử dụng một tuyến đường khác nhau.

Không rõ nội dung nào ở trên tùy thuộc vào chi tiết triển khai so với giao diện. Sự kiện $routeChangeSuccess chắc chắn là tài liệu, nhưng thuộc tính $$route của trường hợp tuyến đường có vẻ là chi tiết triển khai của hệ thống tuyến đường với tên ký hiệu đô la đôi của nó. Chi tiết rằng tuyến đường "khác" được lưu giữ trong bảng định tuyến với khóa null cũng có thể là chi tiết triển khai. Vì vậy, với tất cả điều này nói, hành vi này có thể không còn hoạt động trong các phiên bản tương lai của AngularJS.

Để biết thêm thông tin, bạn có thể tham khảo the ng-view code that handles this event, điều cuối cùng là mã trên đang cố gắng vui lòng, cùng với the event emitting code mà tôi đã sử dụng làm cơ sở cho ví dụ trên. Như bạn có thể phỏng đoán từ các liên kết này, thông tin trong bài đăng này được bắt nguồn từ nhánh chủ mới nhất của AngularJS, tại thời điểm viết được gắn nhãn là ảnh chụp nhanh 1.2.0.

Các vấn đề liên quan