web-dev-qa-db-fra.com

Angular 2 Comment détecter une pression sur le bouton Précédent à l'aide de router et location.go ()

J'ai construit une application qui utilise router 3.0.0-beta.1 pour basculer entre les sections de l'application. J'utilise aussi location.go() pour émuler le passage d'une sous-section à l'autre de la même page. J'ai utilisé <base href="/"> et quelques règles de réécriture d'URL afin de rediriger toutes les routes vers index.html en cas d'actualisation de la page. Cela permet au routeur de recevoir la sous-section demandée sous forme de paramètre d'URL. En gros, j'ai réussi à éviter d'utiliser la variable HashLocationStrategy.

routes.ts

export const routes: RouterConfig = [
    {
        path: '',
        redirectTo: '/catalog',
        pathMatch: 'full'
    },
    {
        path: 'catalog',
        component: CatalogComponent
    },
    {
        path: 'catalog/:topCategory',
        component: CatalogComponent
    },
    {
        path: 'summary',
        component: SummaryComponent
    }
];

Si je clique sur une sous-section de la barre de navigation, 2 choses se passent:

  • logation.go() met à jour l'URL avec la chaîne nécessaire afin d'indiquer la sous-section en cours
  • Une animation personnalisée scrollTo() fait défiler la page en haut de la sous-section demandée.

Si j'actualise la page, j'utilise l'itinéraire précédemment défini et extrait le paramètre nécessaire à la restauration. Faites défiler jusqu'à la sous-section demandée.

this._activatedRoute.params
    .map(params => params['topCategory'])
    .subscribe(topCategory => {
        if (typeof topCategory !== 'undefined' &&
            topCategory !== null
        ) {
            self.UiState.startArrowWasDismised = true;
            self.UiState.selectedTopCategory = topCategory;
        }
    });

Tout fonctionne bien sauf lorsque je clique sur le bouton retour. Si la page précédente était une section différente, le routeur de l'application se comporte comme prévu. Toutefois, si la page/URL précédente était une sous-section, l’URL est remplacée par la précédente, mais il ne se passe rien dans l’UI. Comment puis-je détecter si le bouton Précédent a été enfoncé afin d'appeler la fonction scrollTo() pour refaire son travail?

La plupart des réponses que j'ai vues sur l'événement onhashchange, mais cet événement ne se déclenchent pas dans mon application car je n'ai pas de hachage dans l'URL après tout ...

9
Adrian Moisa

Je ne sais pas si les réponses sont datées, mais aucune d’elles n’a bien fonctionné pour moi dans Angular 2. Ce que j’ai fait, c’est d’ajouter un auditeur d’événement Angular 2 en l’important dans mon composant: 

import { HostListener } from '@angular/core';

puis écoutez popstate sur l'objet window (comme Adrian l'a recommandé):

  @HostListener('window:popstate', ['$event'])
  onPopState(event) {
    console.log('Back button pressed');
  }

Ce code fonctionne pour moi sur le dernier angulaire 2. 

9
VSO

Pour détecter le bouton Précédent du navigateur, cliquez sur Importer platformlocation de '@ angular/common et placez le code ci-dessous dans votre constructeur:

 constructor(location: PlatformLocation) {
     location.onPopState(() => {
        alert(window.location);
     }); }
5
Shivakumar NH

La documentation angulaire indique directement dans la classe PlatformLocation ...

  • Cette classe ne doit pas être utilisée directement par un développeur d'application.

J'ai utilisé LocationStrategy dans le constructeur

constructor(location: LocationStrategy) {
  location.onPopState(() => {
    alert(window.location);
  });
}
4
Rmalmoe

Je suis d'accord avec Adrian Moisa répondre,

mais vous pouvez utiliser "more Angular 2 way" en utilisant class PlatformLocation en injectant dans votre composant ou service, vous pouvez alors définir le rappel onPopState de la manière suivante:

this.location.onPopState(()=>{
  // your code here...
  this.logger.debug('onpopstate event');
});
3
vanrado

Utiliser onpopstate event a fait l'affaire:

window.addEventListener('popstate',
    // Add your callback here
    () => self.events.scrollToTopCategory.emit({ categId: self.state.selectedTopCategory })
);
1
Adrian Moisa

Une excellente méthode consiste à importer «fromEvent» de rxjs et à l'utiliser de cette façon.

fromEvent(window, 'popstate')
  .subscribe((e) => {
    console.log(e, 'back button');
  });
0
Ryann Galea