web-dev-qa-db-fra.com

angularjs obtenant le chemin de route précédent

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

Dans mon module de configuration

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

Contrôleurs

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'};
}

Comme vous pouvez le voir dans mes contrôleurs, j'ai codé en dur l'URL et le texte du bouton de retour (en fait, je n'ai pas besoin du texte pour utiliser une image). De cette façon, j'ai trouvé le bouton de navigation incorrecte dans certains cas. Je ne peux pas utiliser history.back() parce que le bouton Précédent se transforme en lien de menu dans la vue d'accueil.

Ma question est donc de savoir comment obtenir le chemin de la route précédente dans les contrôleurs ou quel est le meilleur moyen de réaliser cela?

J'ai créé une démonstration Plunker de mon problème. S'il vous plaît vérifier cela.

49
Gihan

Cette alternative fournit également une fonction de retour.

Le gabarit:

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

Le module:

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

});
74
andersh

Utilisez les événements $ locationChangeStart ou $ locationChangeSuccess , 3ème paramètre:

$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);
});
22
Mark Rajcok

Dans votre html:

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

Sur votre contrôleur principal:

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

Lorsque l'utilisateur clique sur le lien Retour, la fonction du contrôleur est appelée et le système revient à la route précédente.

16
Mohd Jafar

@andresh Pour moi, locationChangeSuccess a fonctionné à la place de 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
      };
5
Shahid

Voici comment je stocke actuellement une référence au chemin précédent dans le $rootScope:

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

Vous aurez besoin de coupler l'écouteur d'événements à $ rootScope dans Angular 1.x, mais vous devriez probablement corriger un peu votre code en ne stockant pas la valeur de l'emplacement précédent dans $ rootScope. Un meilleur endroit pour stocker la valeur serait un service:

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

Juste pour documenter:

L'argument de rappel previousRoute a une propriété appelée $route qui ressemble beaucoup au $route un service. Malheureusement, l'argument currentRoute ne contient pas beaucoup d'informations sur la route en cours.

Pour surmonter cela, j'ai essayé quelque chose comme ça.

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

Veuillez noter que dans les routes ci-dessus, une propriété personnalisée appelée routeName est ajoutée.

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)
    })
})
1

modification pour le code ci-dessus:

$scope.$on('$locationChangeStart',function(evt, absNewUrl, absOldUrl) {
   console.log('prev path: ' + absOldUrl.$$route.originalPath);
});
1
danikoren