Angular 8 中的页面导航不会触发 canDeactivate()
canDeactivate() is not triggered on page navigation in Angular 8
我需要在从当前组件导航到不同组件时向用户抛出一个弹出窗口。
根据用户的输入,我将不得不允许他离开或让他留下。
经过大量谷歌搜索后,我发现使用实现 canDeactivate 接口的路由保护是解决此问题的最佳方法。
然而,即使按照逐步实施守卫的过程,守卫中实施的 canDeactivate() 方法也永远不会在离开我的组件的任何导航中触发。
这是我作为服务实施的守卫。
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, CanDeactivate } from '@angular/router';
import { Observable } from 'rxjs';
import { SearchProjectComponent } from 'src/app/Project/search-project/search-project.component';
@Injectable({
providedIn: 'root'
})
export class CanDeactivateGuard implements CanDeactivate<SearchProjectComponent> {
canDeactivate(component: SearchProjectComponent,
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot) {debugger
alert('called from guard');
const url: string = state.url;
console.log('Url: ' + url);
return component.canDeactivate ? component.canDeactivate() : true;
}
}
SearchComponent 是我尝试为其实施 Guard 的组件。 (离开这个组件时,我想抛出一个弹出提示)
这是我的 AppRoutingModule
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { AuthGuard } from './shared';
import { CanDeactivateGuard } from './shared/services/can-deactivate-guard.service';
const routes: Routes = [
{ path: '', loadChildren: () => import('./layout/layout.module').then(m => m.LayoutModule), canActivate: [AuthGuard] },
{ path: 'login', loadChildren: () => import('./login/login.module').then(m => m.LoginModule) },
{ path: 'access-denied', loadChildren: () => import('./access-denied/access-denied.module').then(m => m.AccessDeniedModule) },
{ path: 'add-project', loadChildren: () => import('./Project/add-project/add-project.module').then(m => m.AddProjectModule) },
// tslint:disable-next-line:max-line-length
{ path: 'search-project', loadChildren: () => import('./Project/search-project/search-project.module').then(m => m.SearchProjectModule), canDeactivate: [CanDeactivateGuard] },
{ path: '**', redirectTo: 'access-denied' },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
从 searchcomponent 导航到任何其他组件时,canDeactivate 方法甚至不会被触发。
这是我组件中的代码。
canDeactivate(): Observable<boolean> | boolean {debugger
alert('called form component');
if (this.registerForm.dirty) {debugger
return false;
//return this.dialogService.confirm('Discard changes for Person?');
}
return true;
}
甚至我组件中的调试器也不会被触发。
有人可以帮我解决我需要更正的问题吗?
(我只是Angular的初学者,但我觉得这个问题是否与routingmodule中的loadchildren()有关)
您缺少在组件内部实现 component.canDeactivate
,这是唯一知道用户是否可以遗漏的组件。
所以,在你的组件中,实现这个:
canDeactivate(): boolean {
return //condition to verify;
}
有关详细信息,请查看此处:
https://angular.io/guide/router#candeactivate-handling-unsaved-changes
我需要在从当前组件导航到不同组件时向用户抛出一个弹出窗口。
根据用户的输入,我将不得不允许他离开或让他留下。
经过大量谷歌搜索后,我发现使用实现 canDeactivate 接口的路由保护是解决此问题的最佳方法。
然而,即使按照逐步实施守卫的过程,守卫中实施的 canDeactivate() 方法也永远不会在离开我的组件的任何导航中触发。
这是我作为服务实施的守卫。
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, CanDeactivate } from '@angular/router';
import { Observable } from 'rxjs';
import { SearchProjectComponent } from 'src/app/Project/search-project/search-project.component';
@Injectable({
providedIn: 'root'
})
export class CanDeactivateGuard implements CanDeactivate<SearchProjectComponent> {
canDeactivate(component: SearchProjectComponent,
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot) {debugger
alert('called from guard');
const url: string = state.url;
console.log('Url: ' + url);
return component.canDeactivate ? component.canDeactivate() : true;
}
}
SearchComponent 是我尝试为其实施 Guard 的组件。 (离开这个组件时,我想抛出一个弹出提示)
这是我的 AppRoutingModule
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { AuthGuard } from './shared';
import { CanDeactivateGuard } from './shared/services/can-deactivate-guard.service';
const routes: Routes = [
{ path: '', loadChildren: () => import('./layout/layout.module').then(m => m.LayoutModule), canActivate: [AuthGuard] },
{ path: 'login', loadChildren: () => import('./login/login.module').then(m => m.LoginModule) },
{ path: 'access-denied', loadChildren: () => import('./access-denied/access-denied.module').then(m => m.AccessDeniedModule) },
{ path: 'add-project', loadChildren: () => import('./Project/add-project/add-project.module').then(m => m.AddProjectModule) },
// tslint:disable-next-line:max-line-length
{ path: 'search-project', loadChildren: () => import('./Project/search-project/search-project.module').then(m => m.SearchProjectModule), canDeactivate: [CanDeactivateGuard] },
{ path: '**', redirectTo: 'access-denied' },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
从 searchcomponent 导航到任何其他组件时,canDeactivate 方法甚至不会被触发。
这是我组件中的代码。
canDeactivate(): Observable<boolean> | boolean {debugger
alert('called form component');
if (this.registerForm.dirty) {debugger
return false;
//return this.dialogService.confirm('Discard changes for Person?');
}
return true;
}
有人可以帮我解决我需要更正的问题吗? (我只是Angular的初学者,但我觉得这个问题是否与routingmodule中的loadchildren()有关)
您缺少在组件内部实现 component.canDeactivate
,这是唯一知道用户是否可以遗漏的组件。
所以,在你的组件中,实现这个:
canDeactivate(): boolean {
return //condition to verify;
}
有关详细信息,请查看此处:
https://angular.io/guide/router#candeactivate-handling-unsaved-changes