我使用Angular 5实现了一个组件的CanDeactivateGuard,如果有一些未保存的更改,它会弹出一个模式:
export interface CanComponentDeactivate {
canDeactivate: (nextStateUrl: string) => Observable<boolean> | boolean;
}
@Injectable()
export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> {
canDeactivate(
component: CanComponentDeactivate,
currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot,
nextState?: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
return component && component.canDeactivate
? component.canDeactivate(nextState.url)
: true;
}
}
我已经将这个保护添加到page2中,如果我从页面1导航到page2,并进行一些更改,然后尝试导航离开,它就可以完美地工作。但是,如果我停留在page2中并刷新页面,然后进行一些更改,并尝试离开,则将调用防护中的canDeactivate方法,但组件值为空,因此它返回true,而不显示确认模式。或者如果我从page2导航到另一个尚未加载的页面。请注意,所有页面都是延迟加载的,并且每个页面都有自己的路由模块。
我已经以同样的方式向page2模块添加了保护:http://plnkr.co/edit/z2OqgTXTiPpTgXcmNiDM?p=preview
我也试着把守卫添加到主守卫,但也不起作用。
有没有什么原因,当我刷新组件为空时,当我从其他页面导航到第2页时,该组件不在保护范围内。
这里有解决它的方法吗?
谢谢
发布于 2019-02-12 17:05:15
有几个选择。我只能让我的应用程序在使用router-outlet进行页面刷新时警告挂起的更改。参见https://stackoverflow.com/a/51145053/2525272。
根据您的环境,您可以使用类似于- https://medium.com/front-end-weekly/angular-how-keep-user-from-lost-his-data-by-accidentally-leaving-the-page-before-submit-4eeb74420f0d的内容来扩展CanDeactivate防护。或者这个- https://code.i-harness.com/en/q/2242097。这里也讨论了这一点,我使用的是- Warn user of unsaved changes before leaving page。关键是将HostListener导入Angular来处理/拦截浏览器的beforeunload事件,这样它就可以通过我们的路由保护,以确保您需要在页面脏时提示用户。简单地添加以下内容将始终提示用户,无论是否有更改,因此这是误导/令人困惑的。如果用户关闭其选项卡或浏览器,它还将始终提示用户,而不管是否由于未保存的更改而需要提示。
// prevent losing changes with page refresh
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = "\o/";
e.returnValue = confirmationMessage; // Gecko, Trident, Chrome 34+
return confirmationMessage; // Gecko, WebKit, Chrome <34
});
或者,像这样引入一个新的CanActivate守卫-- https://www.bennadel.com/blog/3368-prevent-routing-to-secondary-view-if-page-refresh-in-angular-5-0-0.htm。
此外,我真的很喜欢这个页面- https://www.concretepage.com/angular-2/angular-candeactivate-guard-example,这是一个关于创建可重用的路由守卫服务的很好的参考。
https://stackoverflow.com/questions/51664459
复制