Cách triển khai history.back () trong angular.js


190

Tôi có chỉ thị là tiêu đề trang web với nút quay lại và tôi muốn nhấp để quay lại trang trước. Làm thế nào để tôi làm điều đó theo cách góc cạnh?

Tôi đã thử:

<header class="title">
<a class="back" ng-class="icons"><img src="../media/icons/right_circular.png" ng-click="history.back()" /></a>
<h1>{{title}}</h1>
<a href="/home" class="home" ng-class="icons"><img src="../media/icons/53-house.png" /></a>   
</header>

và đây là chỉ thị js:

myApp.directive('siteHeader', function () {
    return {
        restrict: 'E',
        templateUrl: 'partials/siteHeader.html',
        scope: {
            title: '@title',
            icons: '@icons'
        }
    };
});

Nhưng không có gì xảy ra. Tôi đã tìm trong API angular.js về vị trí $ nhưng không tìm thấy gì về nút quay lại hoặc history.back().


1
Bạn đã đề cập rằng điều này làm việc cho bạn. Nó đưa bạn đến các trang khác nhau trong ứng dụng của bạn hay chỉ là trình duyệt quay lại? Có vẻ như nó làm trình duyệt trở lại với tôi.
Chookoos

Nếu bạn đã đặt AngularJS sử dụng chế độ HTML5, đi đến bất kỳ trang nào đã có trong lịch sử của trình duyệt sẽ sử dụng phiên bản được lưu trong bộ nhớ cache và không tải lại. Dự án tôi đang thực hiện sử dụng hỗn hợp mã cũ và mã mới và trang trước đó thay đổi sau khi dữ liệu được lưu với AngularJS. Đây không phải là một tùy chọn để nâng cấp trang đầu tiên sử dụng AngularJS, vì vậy tôi phải tải trang thứ ba, không phải AngularJS để chuyển hướng trở lại trang đầu tiên. Không phải là một giải pháp tốt đẹp, nhưng nó hoạt động.
CJ Dennis

Câu trả lời:


262

Bạn cần sử dụng chức năng liên kết trong chỉ thị của mình:

link: function(scope, element, attrs) {
     element.on('click', function() {
         $window.history.back();
     });
 }

Xem jsFiddle .


Nhưng tôi có 2 nút trong tiêu đề của mình là một cho nhà và một cho quay lại nếu tôi hiểu mã của bạn, phần tử trong hàm liên kết là phần tử được nhấp trong trường hợp đó. Lịch sử cũng sẽ áp dụng cho nút home? (Điều này không tốt )
baba-dev

Tôi đã thay đổi ví dụ một chút. Bây giờ có hai nút (trở lại và chuyển tiếp). Bây giờ nó sử dụng jQuery, có nghĩa là phạm vi. $ Áp dụng () là cần thiết khi nhấp.
vào

8
Mã này là không thể kiểm chứng, bạn thực sự nên sử dụng đối tượng '$ window' thay vì 'window.'
Trọng tài

Cái này có hoạt động với IE8 không? Tôi không tin rằng nó có lịch sử
Neil

5
@Neil, Angular tự hào không hỗ trợ IE8. Vì vậy, không.
Rap

133

Các tuyến đường xem vị trí của trình duyệt, vì vậy chỉ cần sử dụng window.history.back()nhấp vào một cái gì đó sẽ hoạt động.

HTML:

<div class="nav-header" ng-click="doTheBack()">Reverse!</div>

JS:

$scope.doTheBack = function() {
  window.history.back();
};

Tôi thường tạo một hàm toàn cầu có tên '$ back' trên bộ điều khiển ứng dụng của mình, mà tôi thường đặt trên thẻ body.

angular.module('myApp').controller('AppCtrl', ['$scope', function($scope) {
  $scope.$back = function() { 
    window.history.back();
  };
}]);

Sau đó, bất cứ nơi nào trong ứng dụng của tôi, tôi chỉ có thể làm <a ng-click="$back()">Back</a>

(Nếu bạn muốn nó dễ kiểm tra hơn, hãy đưa dịch vụ $ window vào bộ điều khiển của bạn và sử dụng $window.history.back()).


9
Tôi khuyên bạn không nên đặt bất cứ thứ gì vào một "chức năng toàn cầu". Có rất nhiều điều có thể xảy ra với nhà nước toàn cầu . Trong trường hợp này, nó chủ yếu là sự biến động của nó. Mã từ bên thứ ba (hoặc nhà phát triển khác, nếu bạn thuộc nhóm lớn), chỉ thị hoặc dịch vụ có thể dễ dàng sửa đổi phạm vi $. $ Trở lại cho trẻ em. Mà có thể khó gỡ lỗi. Thực sự tốt hơn là tiêm một dịch vụ vào từng thành phần và hiển thị các chức năng khi cần thiết. Ví dụ này chỉ là "toàn cầu cho ứng dụng", nhưng có rủi ro
Ben Lesh

Nguồn: Tôi đã có những thứ tôi mắc kẹt trong một ứng dụng "toàn cầu" phạm vi $ cắn tôi quá nhiều lần để đếm và tôi đã ngừng sử dụng kỹ thuật đó để ủng hộ các dịch vụ. Mà vẫn có thể bị giẫm đạp, nhưng cách dễ dàng hơn để nói ra.
Ben Lesh

65

Tốt nhất là sử dụng một lệnh đơn giản để giữ cho các bộ điều khiển không có cửa sổ $ dự phòng

app.directive('back', ['$window', function($window) {
        return {
            restrict: 'A',
            link: function (scope, elem, attrs) {
                elem.bind('click', function () {
                    $window.history.back();
                });
            }
        };
    }]);

Sử dụng như thế này:

<button back>Back</button>

Vui mừng bạn đã cho thấy sự phụ thuộc cửa sổ $ - đó là điều quan trọng.
Chris Smith

20

Một giải pháp hay và có thể tái sử dụng khác là tạo một lệnh như thế này :

app.directive( 'backButton', function() {
    return {
        restrict: 'A',
        link: function( scope, element, attrs ) {
            element.on( 'click', function () {
                history.back();
                scope.$apply();
            } );
        }
    };
} );

sau đó chỉ cần sử dụng nó như thế này:

<a href back-button>back</a>

1
Có vẻ như sẽ hoạt động khi bạn sắp xếp lại các xoăn đóng và đổi tên chỉ thị và phần tử attr để khớp với nhau.
lại

18

Trong trường hợp nó hữu ích ... Tôi đã đạt đến "lần lặp 10 $ digest () đạt được. Hủy bỏ!" lỗi khi sử dụng $ window.history.back (); với IE9 (tất nhiên hoạt động tốt trong các trình duyệt khác).

Tôi đã làm cho nó hoạt động bằng cách sử dụng:

setTimeout(function() {
  $window.history.back();
},100);

Các câu trả lời khác sử dụng đồng bằng window. Bạn dường như đang sử dụng $windowdịch vụ Angular. Có lẽ đây là nguyên nhân gốc rễ?
superjos

7
Tôi đã gặp lỗi tương tự trong IE9 và điều này đã giải quyết vấn đề. Xem github.com/angular/angular.js/issues/1417 Anh ấy đúng về việc sử dụng $ window, tất cả các câu trả lời khác là "sai" về điểm này, xem docs.angularjs.org/api/ng.$window
tanguy_k

Bất cứ ý tưởng về lý do tại sao 100ms? Đó là một sự chậm trễ, nó làm việc với ít hơn?
Kevin

@Kevin 100ms chỉ là một khoảng thời gian mà tôi nghĩ là hợp lý và không đáng chú ý. Thật vậy, một độ trễ nhỏ hơn có thể làm việc.
Rob Bygrave

Tôi gặp các vấn đề tương tự trong Chrome mới nhất khi sử dụng điều hướng mặc định Angular trong ứng dụng của mình và sự chậm trễ cũng không giúp được gì. Chỉ vô hiệu hóa quản lý điều hướng của Angular .
Domi

3

Hoặc đơn giản là bạn có thể sử dụng mã:

onClick="javascript:history.go(-1);"

Giống:

<a class="back" ng-class="icons">
   <img src="../media/icons/right_circular.png" onClick="javascript:history.go(-1);" />
</a>

1
Điều này có vẻ sai trên nhiều cấp độ, xem bài đăng trên blog này từ gần 10 năm trước
Rocco

1

Có một lỗi cú pháp. Hãy thử điều này và nó sẽ hoạt động:

directives.directive('backButton', function(){
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.bind('click', function () {
                history.back();
                scope.$apply();
            });
        }
    }
});

1

Góc 4:

/* typescript */
import { Location } from '@angular/common';
// ...

@Component({
  // ...
})
export class MyComponent {

  constructor(private location: Location) { } 

  goBack() {
    this.location.back(); // go back to previous location
  }
}

0

Đối với tôi, vấn đề của tôi là tôi cần điều hướng trở lại và sau đó chuyển sang trạng thái khác. Vì vậy, việc sử dụng $window.history.back()không hoạt động vì một số lý do quá trình chuyển đổi đã xảy ra trước history.back () xảy ra nên tôi phải kết thúc quá trình chuyển đổi của mình trong một hàm thời gian chờ như vậy.

$window.history.back();
setTimeout(function() {
  $state.transitionTo("tab.jobs"); }, 100);

Điều này đã khắc phục vấn đề của tôi.


0

Trong AngularJS2 tôi đã tìm thấy một cách mới, có thể chỉ là điều tương tự nhưng trong phiên bản mới này:

import {Router, RouteConfig, ROUTER_DIRECTIVES, Location} from 'angular2/router'; 

(...)

constructor(private _router: Router, private _location: Location) {}

onSubmit() {
    (...)
    self._location.back();
}

Sau chức năng của tôi, tôi có thể thấy rằng ứng dụng của tôi sẽ chuyển đến vị trí sử dụng trang trước đó từ angular2 / bộ định tuyến.

https://angular.io/docs/ts/latest/api/common/index/Location- class.html


Nó hoạt động, bạn phải nhập nó từ @ angular / common, không phải @ angular / router.
plexus
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.