angularjs получает предыдущий путь маршрута

<h1>{{header}}</h1>
<!-- This Back button has multiple option -->
<!-- In home page it will show menu -->
<!-- In other views it will show back link -->
<a ng-href="{{back.url}}">{{back.text}}</a>
<div ng-view></div>

В моей конфигурации модуля

  $routeProvider.
  when('/', {
    controller:HomeCtrl,
    templateUrl:'home.html'
  }).
  when('/menu', {
    controller:MenuCtrl,
    templateUrl:'menu.html'
  }).
  when('/items', {
    controller:ItemsCtrl,
    templateUrl:'items.html'
  }).
  otherwise({
    redirectto:'/'
  });

Контроллеры

function HomeCtrl($scope, $rootScope){
  $rootScope.header = "Home";
  $rootScope.back = {url:'#/menu', text:'Menu'};
}

function MenuCtrl($scope, $rootScope){
  $rootScope.header = "Menu";
  $rootScope.back = {url:'#/', text:'Back'};
}

function ItemsCtrl($scope, $rootScope){
  $rootScope.header = "Items";
  $rootScope.back = {url:'#/', text:'Back'};
}

Как вы можете видеть в моих контроллерах, я жестко закодировал URL-адрес кнопки «Назад» и текст (на самом деле мне не нужен текст, поскольку я использую изображение). Таким образом, я обнаружил, что в некоторых случаях кнопка «Назад» перемещается неправильно. Я не могу использовать history.back(), потому что моя кнопка «Назад» меняется на ссылку меню в домашнем представлении.

Итак, мой вопрос: как мне получить предыдущий путь маршрута в контроллерах или это лучший способ добиться этого?

Я создал Plunker, демонстрирующий мою проблему. Пожалуйста, проверьте это.


person Gihan    schedule 02.03.2013    source источник
comment
Зачем вам нужно вручную обрабатывать навигацию с помощью кнопки «Назад», когда AngularJS по умолчанию предоставляет функциональные возможности кнопки «Назад»/глубокой ссылки (пример: wordcharconvertor.rogtopia .com)?   -  person Stewie    schedule 02.03.2013
comment
@stewie Извините, я новичок в angularjs и не совсем понял, что вы имеете в виду. Не могли бы вы привести лучший пример с лучшим объяснением? Обратите внимание, что поведение моей навигации по обратной ссылке немного отличается от кнопки «Назад» в браузере.   -  person Gihan    schedule 02.03.2013
comment
Вы должны следовать ответу @MarkRajcok.   -  person Stewie    schedule 03.03.2013
comment
Я собирался проголосовать за это, но вы не отметили ответ @andersh.   -  person im1dermike    schedule 12.11.2015


Ответы (8)


Эта альтернатива также обеспечивает функцию «назад».

Шаблон:

<a ng-click='back()'>Back</a>

Модуль:

myModule.run(function ($rootScope, $location) {

    var history = [];

    $rootScope.$on('$routeChangeSuccess', function() {
        history.push($location.$$path);
    });

    $rootScope.back = function () {
        var prevUrl = history.length > 1 ? history.splice(-2)[0] : "/";
        $location.path(prevUrl);
    };

});
person andersh    schedule 19.09.2013
comment
Кстати, я не думаю, что вам нужно использовать $location, так как обратный вызов $routeChangeSucces вызывается с двумя параметрами: текущий, следующий. docs.angularjs.org/api/ngRoute.$route - person Kenneth Lynne; 22.11.2013
comment
@KennethLynne Я пытался использовать current.$$route.originalPath вместо $location.$$path, но параметры маршрута заполнялись только при использовании $location. Если вы не используете параметры маршрута, ваше предложение должно работать. - person Austin Thompson; 18.03.2014
comment
Его следует использовать с локальным хранилищем для постоянства. В противном случае история будет удалена при обновлении страницы. - person Gihan; 12.02.2016
comment
Вы сохраняете в rootscope, но когда страница обновляется (когда пользователь вводит ctrl + F5), она исчезает, верно?? Итак, где хранить эту обратную функцию???? - person sudhir; 19.04.2016
comment
Да @sudhir, история не сохраняется при обновлении страницы, если вам нужно сохранить ее, вам, вероятно, следует использовать локальное хранилище для хранения массива истории. - person andersh; 19.04.2016

Используйте события $locationChangeStart или $locationChangeSuccess, третий параметр:

$scope.$on('$locationChangeStart',function(evt, absNewUrl, absOldUrl) {
   console.log('start', evt, absNewUrl, absOldUrl);
});
$scope.$on('$locationChangeSuccess',function(evt, absNewUrl, absOldUrl) {
   console.log('success', evt, absNewUrl, absOldUrl);
});
person Mark Rajcok    schedule 23.07.2013
comment
Спасибо @ArturBodera, я вижу, что они теперь задокументированы здесь: docs.angularjs.org/api /ng.$location#events Я обновил ответ. - person Mark Rajcok; 09.12.2013
comment
Это спасло мой день ... У меня была проблема с невозможностью перезагрузить контроллер, когда один из $routeParams изменился из-за того, что пользователь использовал кнопки «назад» и «вперед» в браузере. С этими событиями я могу поймать эту навигацию. - person Bartłomiej Zalewski; 02.12.2014

В вашем HTML:

<a href="javascript:void(0);" ng-click="go_back()">Go Back</a>

На главном контроллере:

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

Когда пользователь нажимает ссылку "Вернуться", вызывается функция контроллера, и он возвращается к предыдущему маршруту.

person Mohd Jafar    schedule 21.04.2016
comment
В моем случае мне не понадобился $, я просто использовал window.history.back(); - person App Dev Guy; 16.06.2016
comment
@AppDevGuy $window — это угловая оболочка для window, и вам рекомендуется использовать ее вместо window, потому что таким образом ее можно смоделировать для тестирования и т. д. Из документов angular (docs.angularjs.org/api/ng/service/$window): в angular мы всегда ссылаемся на него [на window] через сервис $window, поэтому его можно переопределить, удалить или смоделировать для тестирования. - person DarthVanger; 13.01.2017

@andresh Для меня сработало locationChangeSuccess вместо routeChangeSuccess.

//Go back to the previous stage with this back() call
var history = [];
$rootScope.$on('$locationChangeSuccess', function() {
    history.push($location.$$path);
});

$rootScope.back = function () {
          var prevUrl = history.length > 1 ? history.splice(-2)[0] : "/";
          $location.path(prevUrl);
          history = []; //Delete history array after going back
      };
person Shahid    schedule 11.07.2015

Вот как я сейчас храню ссылку на предыдущий путь в $rootScope:

run(['$rootScope', function($rootScope) {
        $rootScope.$on('$locationChangeStart', function() {
            $rootScope.previousPage = location.pathname;
        });
}]);
person daveoncode    schedule 23.02.2015

Вам нужно будет связать прослушиватель событий с $rootScope в Angular 1.x, но вам, вероятно, следует немного проверить свой код в будущем, не сохраняя значение предыдущего местоположения в $rootScope. Лучшим местом для хранения значения будет служба:

var app = angular.module('myApp', [])
.service('locationHistoryService', function(){
    return {
        previousLocation: null,

        store: function(location){
            this.previousLocation = location;
        },

        get: function(){
            return this.previousLocation;
        }
})
.run(['$rootScope', 'locationHistoryService', function($location, locationHistoryService){
    $rootScope.$on('$locationChangeSuccess', function(e, newLocation, oldLocation){
        locationHistoryService.store(oldLocation);
    });
}]);
person Trendy    schedule 03.11.2015
comment
разумное решение - цель - сохранить URL-адрес глобально, в противном случае для отдельных случаев решение @MarkRajcok - хороший способ - person Rafael Ruiz Tabares; 29.04.2016

Просто документировать:

Аргумент обратного вызова previousRoute имеет свойство $route, которое очень похоже на сервис $route. К сожалению, аргумент currentRoute не содержит достаточно информации о текущем маршруте.

Чтобы преодолеть это, я пробовал что-то вроде этого.

$routeProvider.
   when('/', {
    controller:...,
    templateUrl:'...',
    routeName:"Home"
  }).
  when('/menu', {
    controller:...,
    templateUrl:'...',
    routeName:"Site Menu"
  })

Обратите внимание, что в приведенной выше конфигурации маршрутов добавлено пользовательское свойство с именем routeName.

app.run(function($rootScope, $route){
    //Bind the `$routeChangeSuccess` event on the rootScope, so that we dont need to 
    //bind in induvidual controllers.
    $rootScope.$on('$routeChangeSuccess', function(currentRoute, previousRoute) {
        //This will give the custom property that we have defined while configuring the routes.
        console.log($route.current.routeName)
    })
})
person Rajkamal Subramanian    schedule 06.03.2013
comment
Я получаю журнал в консоли, но я все еще не вижу, как вернуться в историю. Я думаю, что столкнулся с ошибкой в ​​Angular с этой проблемой: stackoverflow.com/questions/17712735/ - person Paul; 19.07.2013

модификация кода выше:

$scope.$on('$locationChangeStart',function(evt, absNewUrl, absOldUrl) {
   console.log('prev path: ' + absOldUrl.$$route.originalPath);
});
person danikoren    schedule 23.02.2014
comment
Эта модификация не работает, если вы используете параметры маршрута. Не заполнены параметры для originalPath - person Austin Thompson; 18.03.2014
comment
$scope.on вызывает ошибку «$scope.on не является функцией». Я думаю, что вместо этого вы используете $scope.$on. - person sunghun; 29.03.2014
comment
Параметр absOldUrl — это предыдущий URL. - person Ivan Ferrer; 21.10.2020