Come implementare history.back () in angular.js


191

Ho una direttiva che è l'intestazione del sito con il pulsante Indietro e voglio fare clic su per tornare alla pagina precedente. Come lo faccio in modo angolare?

Ho provato:

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

e questa è la direttiva js:

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

ma non succede nulla. Ho cercato nell'API angular.js circa $ location ma non ho trovato nulla sul pulsante Indietro o history.back().


1
Hai detto che questo ha funzionato per te. Ti porta a pagine diverse all'interno della tua app o semplicemente il browser torna indietro? Sembra che mi risponda al browser.
— Chookoos,

Se hai impostato AngularJS per utilizzare la modalità HTML5, andando su qualsiasi pagina già nella cronologia del browser verrà utilizzata la versione memorizzata nella cache e non ricaricata. Il progetto a cui sto lavorando utilizza una combinazione di vecchio e nuovo codice e la pagina precedente cambia dopo che i dati sono stati salvati con AngularJS. Non è un'opzione per aggiornare la prima pagina per utilizzare AngularJS, quindi ho dovuto caricare una terza pagina non AngularJS per reindirizzare alla prima. Non è una bella soluzione, ma funziona.
— CJ Dennis,

Risposte:


262

È necessario utilizzare una funzione di collegamento nella direttiva:

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

Vedi jsFiddle .


Ma ho 2 pulsanti nella mia intestazione uno per home e uno per back se capisco il tuo codice l'elemento nella funzione link è l'elemento che è stato cliccato nella case history.back si applicherà anche per il pulsante home? (Che non va bene )
— baba-dev,

Ho cambiato un po 'l'esempio. Ora ci sono due pulsanti (avanti e indietro). Ora utilizza jQuery, il che significa che scope. $ Apply () è necessario al clic.
— asgoth,

8
Questo codice non è testabile, dovresti davvero usare l'oggetto "$ window" invece di "window".
— Arbitro

Funziona con IE8? Non credo che abbia una storia
— Neil,

5
@Neil, Angular non supporta IE8 con orgoglio . Quindi no.
— Rap

133

I percorsi angolari osservano la posizione del browser, quindi semplicemente usando window.history.back() facendo clic su qualcosa funzionerebbe.

HTML:

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

JS:

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

Di solito creo una funzione globale chiamata '$ back' sul mio controller di app, che di solito metto sul tag body.

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

Quindi ovunque nella mia app posso solo fare <a ng-click="$back()">Back</a>

(Se si desidera che sia più testabile, iniettare il servizio $ window nel controller e utilizzare $window.history.back()).


9
Consiglio di non mettere nulla in una "funzione globale". Ci sono molte cose che possono accadere allo stato globale . In questo caso è principalmente la volatilità di esso. Il codice di terze parti (o di un altro sviluppatore, se fai parte di una grande squadra), per esempio, una direttiva o un servizio potrebbe facilmente modificare il $ scope. $ Back per i suoi figli. Che potrebbe essere difficile da eseguire il debug. È sicuramente una buona pratica iniettare un servizio in ciascun componente ed esporre la funzionalità dove necessario. L'esempio è solo "globale per l'app", ma c'è rischio
— Ben Lesh,

Fonte: ho avuto cose che ho bloccato in un'app "globale" $ scope mi ha morso troppe volte per contare, e ho smesso di usare quella tecnica a favore dei servizi. Che può ancora essere calpestato, ma è molto più facile uscire.
— Ben Lesh,

65

Utilizzare idealmente una semplice direttiva per mantenere i controller liberi da $ window ridondante

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

Usa così:

<button back>Back</button>

Sono contento che tu abbia mostrato la dipendenza $ window - questo è importante.
— Chris Smith,

20

Un'altra soluzione piacevole e riutilizzabile è quella di creare una direttiva come questa :

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

quindi usalo così:

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

1
Sembra funzionare una volta riordinato il curly di chiusura e rinominato la direttiva e l'elemento attr per abbinarsi l'un l'altro.
— rimessa in servizio il

18

Nel caso sia utile ... Stavo colpendo le "10 $ digest () iterazioni raggiunte. Interruzione!" errore durante l'utilizzo di $ window.history.back (); con IE9 (funziona bene con altri browser ovviamente).

Ho funzionato usando:

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

Altre risposte fanno uso di pianura window. Sembra che tu stia utilizzando il $windowservizio angolare. Forse questa è la causa principale?
— superjos

7
Ho avuto lo stesso errore in IE9 e questo ha risolto il problema. Vedi github.com/angular/angular.js/issues/1417 Ha ragione sull'uso di $ window, tutte le altre risposte sono "sbagliate" su questo punto, vedi docs.angularjs.org/api/ng.$window
— tanguy_k

Qualche idea sul perché 100ms? È un bel ritardo, funziona con meno?
— Kevin,

@Kevin I 100ms erano solo una durata che pensavo fosse ragionevole e che non si notava. In effetti un ritardo minore potrebbe funzionare.
— Rob Bygrave,

Ottengo problemi simili nell'ultimo Chrome quando utilizzo la navigazione predefinita Angular nella mia app e il ritardo non aiuta neanche. Solo la disabilitazione della gestione della navigazione di Angular ha aiutato.
— Domi,

3

Oppure puoi semplicemente usare codice :

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

Piace:

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

1
questo sembra sbagliato su così tanti livelli, cfr. questo post sul blog di quasi 10 anni fa
— Rocco

1

Si è verificato un errore di sintassi. Prova questo e dovrebbe funzionare:

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

1

Angolare 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

Per me, il mio problema era che dovevo tornare indietro e poi passare a un altro stato. Quindi l'utilizzo $window.history.back()non ha funzionato perché per qualche motivo la transizione è avvenuta prima che history.back () si sia verificato, quindi ho dovuto concludere la mia transizione in una funzione di timeout in questo modo.

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

Questo risolto il mio problema.


0

In AngularJS2 ho trovato un nuovo modo, forse è la stessa cosa ma in questa nuova versione:

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

(...)

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

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

Dopo la mia funzione, posso vedere che la mia applicazione sta andando alla posizione d'uso della pagina precedente da angular2 / router.

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


Funziona, devi importarlo da @ angular / common, non @ angular / router.
— plesso,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.