angular - El comportamiento predeterminado del botón Atrás del navegador sigue ejecutándose al detener la propagación
Tengo un sitio en Angular en el que he insertado un código para que el botón de retroceso del navegador se comporte de la misma manera que el botón de retroceso de la interfaz. Sin embargo, cuando presiono retroceder en el navegador, veo parpadear la última página visitada durante un segundo antes de que se ejecute el comportamiento predeterminado.
Aquí hay un video para mostrar lo que quiero decir: al final muestro lo que hace hacer clic en el botón de la interfaz de usuario, que es lo que quiero emular: Demostración del botón de retroceso del navegador
Y aquí está el código que estoy usando en Angular:
@HostListener('window:popstate', ['$event'])
onBrowserBackBtnClose(event: Event) {
// Stop default behavior of the back button
event.stopPropagation();
event.preventDefault();
// If we can go back...
if (this.canGoBack) {
// Load the previous question
this.questionService.previousQuestion().subscribe(res => {
// Activate the question route in place of the previous page
this.router.navigate(['question'], {replaceUrl: true});
});
}
}
Mi entendimiento era que event.stopPropagation(); y event.preventDefault(); detenían este comportamiento de parpadeo. ¿O hay algo más que no estoy entendiendo o que me estoy perdiendo?
Respuesta #1
Si yo fuera tú, preferiría usar el enfoque nativo de Angular aquí. En este caso particular, puedes implementar CanDeactivate o CanActivate en los Guards de Ruta.
En ambos métodos de esta interfaz se utilizan retornos asincrónicos como:
Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree
Respuesta #2
No puedes cancelar el evento popstate en el navegador, lee más sobre el evento en la página de MDN. Dicho esto, puedes actualizar el historial de la ventana (técnicamente un truco) y volver a insertar la ubicación actual para que la página navegue de nuevo a la página actual usando:
window.history.pushState(null, null, window.location.pathname);
No estoy seguro de cómo puedes aplicarlo a tu código, ya que no tengo una demostración funcional de tu aplicación, pero podría verse algo así:
@HostListener('window:popstate', ['$event'])
onBrowserBackBtnClose(event: Event) {
// prevent browser from moving to different page
window.history.pushState(null, null, window.location.pathname);
// If we can go back...
if (this.canGoBack) {
// Load the previous question
this.questionService.previousQuestion().subscribe(res => {
// Activate the question route in place of the previous page
this.router.navigate(['question'], {
replaceUrl: true
}); // you will need some other code to determine and navigate to next page if user chooses to
});
}
}