如何调用 canDeactivate 在 Angular 中单击注销时



在我当前的注销调用中,我有这样的东西:

 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 语句中。因此,不会自动调用您的注销服务。通过这样做,您可以解决问题