【发布时间】:2017-04-08 17:12:39
【问题描述】:
如果我在视图中有一个表单(Angular)。当用户试图离开那里时,我希望出现一条确认消息。我该怎么做?
【问题讨论】:
标签: angular
如果我在视图中有一个表单(Angular)。当用户试图离开那里时,我希望出现一条确认消息。我该怎么做?
【问题讨论】:
标签: angular
您可以使用 typescript 之类的方式实现 canDeactivate
import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
import { ViewthatyouwantGuard } from './path to your view';
@Injectable()
export class ConfirmDeactivateGuard implements CanDeactivate<ViewthatyouwantGuard> {
canDeactivate(target: ViewthatyouwantGuard) {
if (target.hasChanges) {
return window.confirm('Do you really want to cancel?');
}
return true;
}
}
// hasChanges - function in 'ViewthatyouwantGuard' which will return true or false based on unsaved changes
// And in your routing file provide root like
{path:'rootPath/', component: ViewthatyouwantGuard, canDeactivate:[ConfirmDeactivateGuard]},
// Last but not least, also this guard needs to be registered accordingly:
@NgModule({
...
providers: [
...
ConfirmDeactivateGuard
]
})
export class AppModule {}
来源:https://blog.thoughtram.io/angular/2016/07/18/guards-in-angular-2.html
【讨论】:
CanDeactivate 可以用于此。您需要将状态传递给canDeactivate 可以访问的服务。
【讨论】:
如果您的网站需要防止多个页面的路线更改,我想使用此服务可能会很方便:
import { Injectable } from '@angular/core';
import { CanActivateChild } from '@angular/router';
@Injectable()
export class NavPreventerService implements CanActivateChild {
locks: any = {};
constructor() {
// Bonus: If necessary also prevent closing the window:
window.addEventListener('beforeunload', (event) => {
if (this.hasRoutingLocks()) {
event.preventDefault();
event.returnValue = '';
}
});
}
canActivateChild() {
if (this.hasRoutingLocks()) {
if (confirm('Leave site?')) {
this.removeAllRoutingLocks();
return true;
}
return false;
}
return true;
}
setRoutingLock(key: string) {
this.locks[key] = true;
}
removeRoutingLock(key: string) {
delete this.locks[key];
}
removeAllRoutingLocks() {
this.locks = {};
}
hasRoutingLocks(): boolean {
return !!Object.keys(this.locks).length;
}
}
当需要阻止导航时,则在你的组件中调用
this.navPreventer.setRoutingLock('quiz-form');
你的应用路由文件应该是这样的:
export const appRoutesLocal: Routes = [
{path: '', canActivateChild: [NavPreventerService], children: [
{path: '', component: HomePageComponent},
]}
];
【讨论】:
在我的示例网站中,用户应该在导航到他/她的个人详细信息页面时验证安全密码。对于所有其他页面,用户不需要安全密码。安全密码验证成功后,只有他应该导航到“个人详细信息”,否则用户应该在同一页面中。
private routerChangeListener() {
this.router.events.subscribe(event => {
if (event instanceof NavigationStart) {
this.isPersonalDetailsNavigation(event.url);
}
});
}
private verfiyIsNavigatingToMedication(url: string) {
url = url.replace('/', '');
if (url === 'personal-details') {
showPinVerficationPopup();
} else {
console.log('This Is Not Personal Details Page Navigation');
}
}
private showPinVerficationPopup() {
if(verificationSuccess) {
// This Will Navigate to Personal Details Page
this.router.navigate(['personal-details']);
} else {
// This Will Prevent Navigation
this.router.navigate([this.router.url]);
}
}
【讨论】: