7

在我当前的注销通话中,我有这样的事情:

 getLogoutConfirmation(){
   // get confirmation in modal and perform logout
   // redirect to login page
 }

问题是,当执行注销并调用重定向到登录时,会在该路由上调用 canDeactivate 守卫,但用户已经注销。

那么如何在执行注销之前调用 canDeactivate 守卫并在用户不想离开时取消注销操作。

谢谢。

4

6 回答 6

2

无需立即注销,只需导航到您的目标(登录?)位置并添加一些额外的参数。然后在您的目标(登录?)位置添加一个“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();
  }
于 2019-04-26T08:47:41.413 回答
2

您应该导航到基于getLogoutConfirmation(). 如果您没有导航离开,则CanDeactivate不会被激活。

否则,当您离开 Angular应用程序中的当前视图或路线时,会调用Guard canDeactivate。您可以在 canDeactivate 中检查并获取 getLogoutConfirmation,然后决定继续或取消导航。CanDeactivate 守卫可用于处理未保存的更改、检查权限和清理组件。这不处理外部导航,例如浏览器刷新或关闭。您需要用于这些情况@HostListener('window:beforeunload')

于 2018-01-10T12:11:51.827 回答
1

我遇到了同样的问题,我通过创建一个组件来解决它,该组件处理 ngOnInit () 中的注销功能,然后重定向到登录页面

 ngOnInit() {
    this.authenticationService.logout();
    this.router.navigate(['/login']);
  }

这将导致路由被停用,从而调用 canDeactivate 守卫并显示确认

于 2018-10-09T11:10:51.260 回答
1

我只有几周的角度经验。这是我的解决方法。我在本地存储中添加了未保存表单的变量检查。

<---------------------------------------------------- --------------------------------->

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.');
  }
  
}
于 2021-09-22T22:06:39.653 回答
1

只需在您的注销呼叫中调用 CanDeactivate ,您就可以在那里进行逻辑:

canDeactivate() {
  if(confirm('Leave and logout ?') {
    this.loginService.logout();
    this.router.navigate('');
    return true;
  } else {
    return false;
  }
}

canDeactivate 只是一个接口的实现,你可以像调用任何函数一样调用它

于 2018-01-10T12:07:25.450 回答
0

我有同样的问题,并通过检查导航响应解决了这个问题。

假设你有 canDeactivate 像这样:

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

于 2020-07-24T10:16:37.410 回答