Як реалізувати history.back () в angular.js


191

У мене є директива - це заголовок сайту з кнопкою "назад", і я хочу, щоб натиснути кнопку, щоб повернутися до попередньої сторінки. Як це зробити кутовим способом?

Я намагався:

<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>

і це директива js:

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

але нічого не відбувається. Я переглянув API angular.js про $ location, але не знайшов нічого про кнопку назад або history.back().


1
Ви згадали, що це працювало на вас. Переходить вас на різні сторінки у вашій програмі чи просто повертається браузер? Схоже, це переглядає мене назад.
Chookoos

Якщо ви встановили AngularJS використовувати режим HTML5, перехід на будь-яку сторінку, яка вже є в історії браузера, буде використовувати кешовану версію, а не перезавантажувати її. Проект, над яким я працюю, використовує суміш старого та нового коду, а попередня сторінка змінюється після збереження даних за допомогою AngularJS. Це не варіант для оновлення першої сторінки, щоб використовувати AngularJS, тому мені довелося завантажити третю, не AngularJS сторінку, щоб перенаправити назад на першу. Не приємне рішення, але воно працює.
CJ Dennis

Відповіді:


262

Вам потрібно використовувати функцію посилання у своїй директиві:

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

Дивіться jsFiddle .


Але у мене в головному заголовку є 2 кнопки - одна для домашньої та одна для зворотної, якщо я розумію ваш код, елемент у функції посилання - це елемент, який було натиснуто в історії цього випадку. )
баба-дев

Я трохи змінив приклад. Зараз є дві кнопки (назад і вперед). Він використовує jQuery зараз, а це означає, що для натискання потрібен $. Application ().
asgoth

8
Цей код не встановлений, вам слід використовувати об’єкт '$ window' замість 'window'.
Арбітр

Це працює з IE8? Я не вірю, що в ній є історія
Ніл

5
@Neil, Angular гордо не підтримує IE8. Отже, ні.
Реп

133

Кутові маршрути відстежують розташування браузера, тому просто window.history.back()натискання на щось щось спрацює.

HTML:

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

JS:

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

Зазвичай я створюю на своєму контролері програми глобальну функцію під назвою "$ назад", яку я зазвичай наношу на тег body.

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

Тоді в будь-якому місці свого додатка я просто можу це зробити <a ng-click="$back()">Back</a>

(Якщо ви хочете, щоб він був більш перевіреним, введіть службу $ window у свій контролер і використовуйте $window.history.back()).


9
Я б рекомендував не ставити нічого в "глобальну функцію". Є дуже багато речей, які можуть трапитися з глобальною державою . У цьому випадку це здебільшого мінливість. Код від третьої сторони (або іншого розробника, якщо ви працюєте у великій команді), наприклад, директива чи послуга можуть легко змінити область застосування $. $ Назад для своїх дітей. Що може бути важким для налагодження. Безумовно, краща практика вводити службу в кожен компонент і розкривати функціонал там, де це потрібно. Приклад лише "глобальний для програми", але є ризик
Бен Леш

Джерело: У мене були речі, які я застряг у "глобальному" додатку $ сфера, кусаючи мене занадто багато разів, щоб рахувати, і я перестав використовувати цю техніку на користь послуг. На яку ще можна натрапити, але це простіше висунути.
Бен Леш

65

В ідеалі використовуйте просту директиву, щоб захистити контролери від зайвих $ window

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

Використовуйте так:

<button back>Back</button>

Радий, що ти показав залежність $ вікна - це важливо.
Кріс Сміт

20

Ще одна приємна і багаторазові рішення створити директиву , як це :

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

тоді просто використовуйте його так:

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

1
Здається, що ви працюєте, коли ви упорядкуєте фігурні фігури, що закриваються, і перейменуєте директиву та елемент attr, щоб вони відповідали один одному.
ремарш

18

У випадку, якщо це корисно ... Я потрапляв на "досягнуті ітерації 10 $ (). Аборт!" помилка при використанні $ window.history.back (); з IE9 (добре працює в інших браузерах, звичайно).

Я змусив його працювати, використовуючи:

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

Інші відповіді використовують просто window. Ви, здається, користуєтесь $windowпослугою Angular. Можливо, це і є першопричиною?
superjos

7
Я отримав таку ж помилку під IE9, і це вирішило проблему. Див. Github.com/angular/angular.js/isissue/1417 Він правильний щодо використання $ window, усі інші відповіді "неправильні" в цьому питанні, див. Docs.angularjs.org/api/ng.$window
tanguy_k

Будь-яка ідея, чому 100 мс? Це досить затримка, чи працює вона з меншими?
Кевін

@Kevin 100 мс - це просто тривалість, яку я вважав розумною і неможливо помітною. Дійсно, менша затримка може спрацювати.
Роб Біграйв

У останніх веб-переглядачах Chrome я отримую подібні проблеми, коли в моїй програмі використовується навігація за замовчуванням, і затримка не допоможе. Лише відключення управління навігацією Angular допомогло.
Домі


1

Виникла помилка синтаксису. Спробуйте це, і це має працювати:

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

1

Кутовий 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

Для мене моєю проблемою було те, що мені потрібно було перейти назад, а потім перейти до іншого стану. Тому використання $window.history.back()не працювало, оскільки чомусь перехід відбувся до того, як відбувся history.back (), тому мені довелося перевести перехід у функцію тайм-аута.

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

Це вирішило мою проблему.


0

У AngularJS2 я знайшов новий спосіб, можливо, саме те саме, але в цій новій версії:

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

(...)

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

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

Після виконання моєї функції я бачу, що моя програма переходить на попередню сторінку Usgin від angular2 / router.

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


Це працює, вам потрібно імпортувати його з @ angular / common, а не @ angular / router.
сплетіння
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.