按下浏览器后退按钮后,CanDeactivate 守卫未按预期运行
CanDeactivate guards does not runs as expected, after pressing browser back button
我已经实现了 canDeactive 防护,单击浏览器按钮后它会弹出一个模型并询问 Yes/No。
单击否后,它会停留在同一页面上,如果我再次按下后退按钮,则会出现弹出窗口,单击 No/Yes 按钮后,它会从浏览器历史记录重定向到空白页面 url,而不是停留在相同 url.
请找到停用守卫的代码。
import { Injectable, HostListener, } from '@angular/core';
import { CanDeactivate, ActivatedRoute, Router, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
:
:
:
:
export abstract class myCompCanDeactivate {
abstract canDeactivate(): boolean;
@HostListener('window:beforeunload', ['$event'])
unloadNotification($event: any) {
if (!this.canDeactivate()) {
$event.returnValue = true;
}
}
}
@Injectable()
export class DeactivateGuardService implements CanDeactivate<myCompCanDeactivate> {
showDashboard:boolean=false;
islogout:any;
sStep:number;
demoLastSection:number = 0;
menuitem:SitefinityPortalMenu;
constructor(private next:ActivatedRoute,private resourceService: ResourceService,
private matDialog: MatDialog,private browserGlobalService: BrowserGlobalService, private route:Router ){}
async canDeactivate(component: myCompCanDeactivate,currentRoute: ActivatedRouteSnapshot, currentState: RouterStateSnapshot, nextState?: RouterStateSnapshot): Promise<boolean> {
if(!component.canDeactivate()){
if (this.browserGlobalService.GlobalLogout=== 'logout') {
this.browserGlobalService.GlobalLogout = '';
return true;
}
//Get Portal left menus from sitefinity.
this.menuitem = await this.resourceService.getPortalMenus("Portal_Left_Menu").toPromise();
var str:SitefinityMenuItem[] = this.menuitem.MenuItems.filter((m)=>{return m.LinkUrl.includes(nextState.url) && m.Hidden===false});
if ( nextState.url!='/demoSite' && nextState.url === (str.length>0?str[0].LinkUrl:'') ){return true; }
this.sStep = SaleSteps.Review;
this.demoLastSection = PSSections.signStep;
if (this.browserGlobalService.PLSavedSection != this.demoLastSection || this.browserGlobalService.PLSavedSection != this.sStep ){
let modalData = new ModalData();
modalData.Header = this.resourceService.getViewLabel("ModalHeader_BrowserBack");
modalData.Body = this.resourceService.getViewLabel("ModalBody_BrowserMessage");
modalData.ControlArray = [
new ButtonAction(this.resourceService.getViewLabel("ModalCancel_Yes"), "YES"),
new ButtonAction(this.resourceService.getViewLabel("ModalCancel_No"), "NO")
];
let dialogRef = this.matDialog.open(GspModalComponent, {
data: modalData
});
dialogRef.afterClosed().subscribe(result => {
if (result && result.toLowerCase() === "yes") {
this.browserGlobalService.callComponentMethod("");
// this.route.navigated = true;
return false;
}
return false;
});
}
}
return false;
}
}
我找到了这个问题的解决方案。
解决方案:history.pushState("","","/sales");
(只是在浏览器历史记录中推送路由器状态)
由于 url 在我的情况下始终保持不变,因此只要按下浏览器后退按钮,就会执行浏览器默认的 activity 。所以它从历史中弹出状态,并在浏览器导航到空白页面后到达最后一个历史状态。
我已经实现了 canDeactive 防护,单击浏览器按钮后它会弹出一个模型并询问 Yes/No。 单击否后,它会停留在同一页面上,如果我再次按下后退按钮,则会出现弹出窗口,单击 No/Yes 按钮后,它会从浏览器历史记录重定向到空白页面 url,而不是停留在相同 url.
请找到停用守卫的代码。
import { Injectable, HostListener, } from '@angular/core';
import { CanDeactivate, ActivatedRoute, Router, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
:
:
:
:
export abstract class myCompCanDeactivate {
abstract canDeactivate(): boolean;
@HostListener('window:beforeunload', ['$event'])
unloadNotification($event: any) {
if (!this.canDeactivate()) {
$event.returnValue = true;
}
}
}
@Injectable()
export class DeactivateGuardService implements CanDeactivate<myCompCanDeactivate> {
showDashboard:boolean=false;
islogout:any;
sStep:number;
demoLastSection:number = 0;
menuitem:SitefinityPortalMenu;
constructor(private next:ActivatedRoute,private resourceService: ResourceService,
private matDialog: MatDialog,private browserGlobalService: BrowserGlobalService, private route:Router ){}
async canDeactivate(component: myCompCanDeactivate,currentRoute: ActivatedRouteSnapshot, currentState: RouterStateSnapshot, nextState?: RouterStateSnapshot): Promise<boolean> {
if(!component.canDeactivate()){
if (this.browserGlobalService.GlobalLogout=== 'logout') {
this.browserGlobalService.GlobalLogout = '';
return true;
}
//Get Portal left menus from sitefinity.
this.menuitem = await this.resourceService.getPortalMenus("Portal_Left_Menu").toPromise();
var str:SitefinityMenuItem[] = this.menuitem.MenuItems.filter((m)=>{return m.LinkUrl.includes(nextState.url) && m.Hidden===false});
if ( nextState.url!='/demoSite' && nextState.url === (str.length>0?str[0].LinkUrl:'') ){return true; }
this.sStep = SaleSteps.Review;
this.demoLastSection = PSSections.signStep;
if (this.browserGlobalService.PLSavedSection != this.demoLastSection || this.browserGlobalService.PLSavedSection != this.sStep ){
let modalData = new ModalData();
modalData.Header = this.resourceService.getViewLabel("ModalHeader_BrowserBack");
modalData.Body = this.resourceService.getViewLabel("ModalBody_BrowserMessage");
modalData.ControlArray = [
new ButtonAction(this.resourceService.getViewLabel("ModalCancel_Yes"), "YES"),
new ButtonAction(this.resourceService.getViewLabel("ModalCancel_No"), "NO")
];
let dialogRef = this.matDialog.open(GspModalComponent, {
data: modalData
});
dialogRef.afterClosed().subscribe(result => {
if (result && result.toLowerCase() === "yes") {
this.browserGlobalService.callComponentMethod("");
// this.route.navigated = true;
return false;
}
return false;
});
}
}
return false;
}
}
我找到了这个问题的解决方案。 解决方案:history.pushState("","","/sales"); (只是在浏览器历史记录中推送路由器状态) 由于 url 在我的情况下始终保持不变,因此只要按下浏览器后退按钮,就会执行浏览器默认的 activity 。所以它从历史中弹出状态,并在浏览器导航到空白页面后到达最后一个历史状态。