在我当前的注销调用中,我有这样的东西:
getLogoutConfirmation(){
// get confirmation in modal and perform logout
// redirect to login page
}
问题是,当执行注销并调用重定向到登录时,在该路由上调用 canDeactivate 保护,但用户已注销。
那么,如何在执行注销之前调用canDeactivate guard,如果用户不想离开,则取消注销操作。
谢谢。
无需立即注销,只需导航到目标(登录?(位置并添加一些额外的参数即可。然后将"canActivate"防护添加到您的目标(登录?(位置,检查您的额外参数,并在那里执行实际注销。这样,注销不会干扰您的 canDeactivate 保护,并且会在正确的时间发生(如果 canDeactivate 说正常(。
改变:
userLogout() {
this.authenticationService.logout();
this.router.navigate(['login']);
}
自:
userLogout() {
this.router.navigate(['login'], { queryParams: { logout: true }});
}
在 canActivate 守卫中,执行以下操作:
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): ... {
if ('true' === next.queryParamMap.get('logout')){
this.authenticationService.logout();
}
根据getLogoutConfirmation()
导航到登录页面。 如果您没有离开,则CanDeactivate
不会被激活。
否则,在角度应用程序中导航离开当前视图或路线时,将调用 Guard canDeactivate 。您可以检查并在canDeactive中获取注销确认,然后决定继续或取消导航。CanDeactivate guard可用于处理未保存的更改,检查权限和清理组件。这不会处理外部导航,例如浏览器刷新或关闭。对于这些情况,您需要使用 @HostListener('window:beforeunload')
只需在注销调用中调用CanDeActivate ,然后在那里逻辑:
canDeactivate() {
if(confirm('Leave and logout ?') {
this.loginService.logout();
this.router.navigate('');
return true;
} else {
return false;
}
}
canDeactivate 只是一个接口的实现,你可以像调用任何函数一样调用它
我遇到了同样的问题,我通过创建一个组件来解决它,该组件处理ngOnInit((中的注销功能,然后重定向到登录页面
ngOnInit() {
this.authenticationService.logout();
this.router.navigate(['/login']);
}
这将导致路由被停用,从而调用CanDeactivate Guard并显示确认
我只有几周的角度经验。这是我的解决方法。我在本地存储中添加了未保存表单的变量检查。
<---------------------------------------------------------------------------------->
header.component.ts
logout(){
this.formDetect= JSON.parse(localStorage.getItem('formDetect'));
var res=true;
if(this.formDetect.isUnsaved){
res=confirm("are you sure you want to logout? You have an unsaved form");
}
if(res){
//If you are using it somewhere else, make sure to set isUnsaved to false then set local storage.
//this.formDetect.isUnsaved=false;
//localStorage.setItem("formDetect", JSON.stringify(this.formDetect));
this.accountService.logout();
this.router.navigateByUrl('/login');
}
}
<---------------------------------------------------------------------------------->
form.component.ts
export class FormComponent implements OnInit, SafeData {
formDetect:FormDetect;
@HostListener('window:beforeunload')
isDataSaved():boolean{
this.formDetect= JSON.parse(localStorage.getItem('formDetect'));
return!this.formDetect.isUnsaved;
}
onFormChange(){
this.formDetect.isUnsaved=true;
localStorage.setItem("formDetect", JSON.stringify(this.formDetect));
}
}
<---------------------------------------------------------------------------------->
export interface SafeData{
isDataSaved():boolean;
}
<---------------------------------------------------------------------------------->
export class FormDetect{
isUnsaved:boolean=false;
}
<---------------------------------------------------------------------------------->
警卫
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanDeactivate, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
import { SafeData } from '../_models/safeData';
@Injectable({
providedIn:"root"
})
export class UnsavedCheckGuard implements CanDeactivate<SafeData> {
canDeactivate(component: SafeData): boolean | Observable<boolean> {
// if there are no pending changes, just allow deactivation; else confirm first
var result= component.isDataSaved();
return result ?
true :
// NOTE: this warning message will only be shown when navigating elsewhere within your angular app;
// when navigating away from your angular app, the browser will show a generic warning message
// see http://stackoverflow.com/a/42207299/7307355
confirm('You have unsaved changes. Press Cancel to go back and save these changes, or OK to lose these changes.');
}
}
我有同样的问题,并通过检查导航响应解决了这个问题。
假设你有这样的可以停用:
canActivate() {
return windows.confirm("you have unsaved work, Are you still want to logout?")
}
因此,使用此功能,您会询问用户是否要在保存任务之前注销?现在,您可以在注销函数中具有此响应。该函数可以像波纹管一样编写:
userLogout() {
this.router.navigate(['login']).then( (response) = > {
//response get the response from canDeactivate
if (response) {
// if response is true, call the logout service
this.authenticationService.logout();
}
}
}
在函数中,如果用户想要离开未保存的任务,您将在userLogout函数中得到true。将此响应放在 if 语句中。因此,不会自动调用您的注销服务。通过这样做,您可以解决问题