Итак, у меня есть приложение SPA, построенное на angular, теперь моя проблема в том, что когда пользователь находится в моем приложении, если он нажимает кнопку возврата (в браузере), иногда, если данные были отправлены на предыдущей странице, это может вызвать ошибки, а иногда есть состояние, что при обновлении уходит. Теперь есть способ предупредить пользователя перед возвратом или просто не разрешить пользователю вернуться?
Я пытался сделать это в своем index.html
<script>
window.onbeforeunload = function() {
return "Message";
};
</script>
но похоже, что это больше не работает в новых браузерах, я нашел аналогичный вопрос здесь, но он был задан несколько лет назад, и я попробовал несколько из них, и ни одно из них не сработало ..
как лучше всего в 2018 году справиться с этой ситуацией ??
Спасибо
Вы можете разрешить / запретить навигацию по маршруту с помощью средства защиты маршрута canActivate
, и вы можете разрешить / запретить переход от маршрута с помощью средства защиты маршрута canDeactivate
(см. документация по Angular).
Если вы хотите запретить пользователю вернуться на страницу, которая уже была посещена, используйте защиту маршрута canActivate
. В этот stackblitz перед возвратом на страницу Login
запрашивается подтверждение. В качестве бонуса он также содержит пример защиты маршрута canDeactivate
для маршрута Home
.
Вот код для защиты маршрута canActivate
маршрута Login
:
активировать-guard.ts
import { Injectable } from "@angular/core";
import { CanActivate, CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot } from "@angular/router";
import { Observable } from "rxjs";
import { LoginActivateService } from "./login-activate.service";
@Injectable()
export class ActivateGuard implements CanActivate {
constructor(private loginActivate: LoginActivateService) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
return this.loginActivate.canActivateLogin || confirm("Do you really want to go back to login?");
}
}
app-routing.module.ts
...
imports: [
RouterModule.forRoot([
{
path: 'login', component: LoginViewComponent,
canActivate: [ActivateGuard]
},
{
path: 'home',
component: HomeViewComponent,
canDeactivate: [DeactivateGuard]
},
...
])
],
будет ли этот триггер для каждого события выгрузки или только кнопка возврата ??
При любой попытке покинуть страницу. Я могу провести больше тестов, чтобы узнать, есть ли способ определить, что причиной была кнопка «Назад».
Да, я бы действительно хотел отображать сообщение только в том случае, если пользователь нажимает кнопку "Назад" и не пытается покинуть приложение.
Вы имеете в виду, что хотите отображать сообщение, когда пользователь нажимает кнопку «Назад» для навигации по приложению? Этот ответ неприменим к этому случаю (как и образец кода в вопросе).
Я имею в виду кнопку назад в браузере
Да, но эта кнопка может заставить браузер покинуть приложение или перейти к предыдущему маршруту в приложении. Какой из них применим к вашему случаю?
Я просто хочу запретить людям использовать кнопку "Назад" для перехода на предыдущие страницы в моем приложении.
Может ли пользователь с этой страницы переходить к другим страницам приложения другими способами, кроме кнопки «Назад»?
Да, у меня есть полная навигация, встроенная в веб-приложение, у пользователя нет причин нажимать кнопку «Назад», но это было просто проблемой.
Извините, еще один вопрос. Пользователю будет разрешено переходить на другие страницы, но вы хотите предотвратить (или предупредить) его от перехода на одну конкретную страницу. Это верно?
чтобы пользователь мог переходить в другие места с помощью навигации приложения, но я хочу запретить им или предупредить их об использовании кнопки «Назад» не только для одной конкретной страницы, но и для любой страницы.
Вы можете использовать охранники маршрута, чтобы предотвратить переход с маршрута (canDeactivate
) или на маршрут (canActivate
), но я не думаю, что они могут отличить использование кнопки возврата от других средств навигации. Если после выхода со страницы вы не хотите, чтобы пользователь возвращался на эту страницу (с кнопкой «Назад» или без нее), это можно сделать с помощью средства защиты маршрута canActivate
.
Я изменил ответ, чтобы показать использование охранников маршрута. Вы можете поэкспериментировать с демонстрацией stackblitz, упомянутой в ответе.
вы можете подписаться на свойство событий маршрутизатора (доступно в Angular 8>) он будет запускать действие на каждой фазе маршрутизации, например, в начале, конце навигации, событии onPopstate, ... и, следовательно, событии кнопки возврата браузера.
import { Router } from '@angular/router';
constructor(private router: Router) {
this.router.events.subscribe((event) => {
if (event instanceof NavigationStart && event.navigationTrigger === 'popstate') {
// write the logic here
}
});
}
Взгляните на
canDeactivate()