acc*_*ris 4 angular angular-router-guards angular-router
我正在尝试使用 canDeactivate 路由器防护。第一次运行代码时,我传入的组件 (ClaimsViewComponent) 为空。但是在随后的运行中,代码会按预期运行。我们试图弄清楚为什么组件在第一次运行时为空。
这是 canDeactivate 守卫代码:
@Injectable()
export class ConfirmDeactivateGuard implements
CanDeactivate<ClaimsViewComponent> {
canDeactivate(target: ClaimsViewComponent): boolean {
if (target.canDeactivate()) {
return window.confirm('Do you really want to cancel?');
}
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
这是路由模块代码:
const routes: Routes = [
{ path: ':type', component: ClaimsViewComponent, canDeactivate:
[ConfirmDeactivateGuard] }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
Run Code Online (Sandbox Code Playgroud)
这是完整的错误堆栈:
TypeError: Cannot read property 'canDeactivate' of null
at ConfirmDeactivateGuard.canDeactivate (confirm-deactivate-guard.ts:16)
at MergeMapSubscriber.eval [as project] (router.js:3933)
at MergeMapSubscriber._tryNext (mergeMap.js:128)
at MergeMapSubscriber._next (mergeMap.js:118)
at MergeMapSubscriber.Subscriber.next (Subscriber.js:95)
at ArrayObservable._subscribe (ArrayObservable.js:116)
at ArrayObservable.Observable._trySubscribe (Observable.js:172)
at ArrayObservable.Observable.subscribe (Observable.js:160)
at MergeMapOperator.call (mergeMap.js:92)
at Observable.subscribe (Observable.js:157)
at ConfirmDeactivateGuard.canDeactivate (confirm-deactivate-guard.ts:16)
at MergeMapSubscriber.eval [as project] (router.js:3933)
at MergeMapSubscriber._tryNext (mergeMap.js:128)
at MergeMapSubscriber._next (mergeMap.js:118)
at MergeMapSubscriber.Subscriber.next (Subscriber.js:95)
at ArrayObservable._subscribe (ArrayObservable.js:116)
at ArrayObservable.Observable._trySubscribe (Observable.js:172)
at ArrayObservable.Observable.subscribe (Observable.js:160)
at MergeMapOperator.call (mergeMap.js:92)
at Observable.subscribe (Observable.js:157)
at resolvePromise (zone.js:814)
at resolvePromise (zone.js:771)
at eval (zone.js:873)
at ZoneDelegate.invokeTask (zone.js:421)
at Object.onInvokeTask (core.js:4740)
at ZoneDelegate.invokeTask (zone.js:420)
at Zone.runTask (zone.js:188)
at drainMicroTaskQueue (zone.js:595)
Run Code Online (Sandbox Code Playgroud)
谢谢你。
看来,canDeactivate不致力于“延迟加载”。请检查您的路线,并确保您已设置该component属性。
更新@rohan-sampat 反馈。
有用。我的项目中也遇到了 CanDeactivate 问题。
CanDeactivate-guard.service.ts
import { Observable } from 'rxjs';
import { CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
export interface CanComponentDeactivate {
canComDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
}
export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> {
canDeactivate(component: CanComponentDeactivate,
currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot,
nextState?: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
return component.canComDeactivate();
}
}
Run Code Online (Sandbox Code Playgroud)
这是我使用 CanDeactivate 进行验证的组件。
import { Component, EventEmitter, Output, OnInit } from "@angular/core";
import { DataService } from '../Shared/Service/DataService';
import { ActivatedRoute } from '@angular/router';
import { Subscription, Observable } from 'rxjs';
import { CanComponentDeactivate } from '../can-deactivate-guard.service';
@Component({
selector: 'app-server',
templateUrl: './server.component.html'
})
export class ServerComponent implements OnInit, CanComponentDeactivate {
@Output() serverCreated = new EventEmitter<string>();
queryParams: Subscription;
data: string;
canMove: false;
userModel: any;
constructor(private dataService: DataService, private route: ActivatedRoute) {
}
ngOnInit() {
this.dataService.dataUpdate.subscribe(data => {
this.data = data;
})
this.queryParams = this.route.queryParams.subscribe(data => {
this.userModel = JSON.parse(data["model"]);
})
}
canComDeactivate(): Observable<boolean> | Promise<boolean> | boolean {
if (this.data == undefined || this.data == "") {
var res = confirm("Text is blank");
return res;
}
return this.canMove;
}
}
Run Code Online (Sandbox Code Playgroud)
我在其中定义了路由的 app.module.ts 文件。
const appRoutes: Routes = [
// { path: '', loadChildren: () => import('./Login/login.module').then(l => l.LoginModule) },
{ path: 'login', loadChildren: () => import('./Login/login.module').then(l => l.LoginModule) },
{ path: 'server', canActivate: [AuthGuard], canDeactivate: [CanDeactivateGuard], loadChildren: () => import('./severs/server.module').then(s => s.ServerModule) },
{ path: '**', component: ErrorComponent },
];
Run Code Online (Sandbox Code Playgroud)
路径服务器上的 CanDeactivate 导致了问题。如果我试图进入模块外的另一条路径,那么 id 甚至不会击中 CanDeactivate 防护。
但是,如果我将 CanDeactivate 从 app.module 放置到 server.routes 文件中,意味着在延迟加载的模块本身中对其进行验证,那么它就可以正常工作,如预期的那样。
Server.route.ts 文件
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { ServerComponent } from './server.component';
import { ErrorComponent } from './404.component';
import { CanDeactivateGuard } from '../can-deactivate-guard.service';
const route: Routes = [
{ path: '', component: ServerComponent },
{ path: 'server:/model', component: ServerComponent, canDeactivate: [CanDeactivateGuard] },
{ path: 'server', component: ServerComponent, canDeactivate: [CanDeactivateGuard] },
{ path: 'not-found', component: ServerComponent },
//{ path: '**', component: ErrorComponent },
]
@NgModule({
imports: [RouterModule.forChild(route)],
exports: [RouterModule]
})
export class ServerRoute { }
Run Code Online (Sandbox Code Playgroud)
现在,在解决方案发生变化之后,我的代码可以正常工作。希望这可以帮助。
| 归档时间: |
|
| 查看次数: |
3492 次 |
| 最近记录: |