我创建了一个CanDeactivate保护程序,它返回一个可观察的,并应用到一个组件中,该组件加载在内部嵌套的路由器出口中。当一个人试图导航到另一个url时,是否应该调用这个守卫?我这么问是因为这不是我的案子。
在我的例子中,守卫只会被调用第一个“不同”的URL。让我用一个例子来解释它。假设我总是返回false,并且尝试从同一个组件导航到不同的urls:
/A --> guard called
/B --> guard called
/B --> no navigation and no guard called
/A --> guard called
/A -->guard not called and no navigation这是预期的行为吗?
编辑很好,看起来是的。刚刚构建了一个包含3个组件的小示例,只有在用户第一次尝试导航到特定的url...this时才会调用保护程序,这真的很奇怪.
总之,这是我使用的代码:
// app.routing
import {NgModule} from "@angular/core";
import {Routes, RouterModule, Route, CanDeactivate, ActivatedRouteSnapshot,
RouterStateSnapshot} from "@angular/router";
import { MainComponent } from "./main/main.component";
import { OtherComponent } from "./other/other.component";
import { Other3Component } from "./other3/other3.component";
import {Observable} from "rxjs/observable";
const fallback: Route = {
path: "**",
redirectTo: "/main",
pathMatch: "full"
};
export class Test implements CanDeactivate<MainComponent>{
canDeactivate(component: MainComponent, route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | boolean{
console.log("in");
return false;
}
}
export const rotas: Routes = [
{
path: "main",
component: MainComponent,
canDeactivate: [Test]
},
{
path: "other",
component: OtherComponent
},
{
path: "other3",
component: Other3Component
},
fallback
];
@NgModule({
imports: [RouterModule.forRoot(rotas)],
exports: [RouterModule]
})
export class AppRoutingModule{}//app.component.html <h1> <a routerLink="/main">Main</a> <a routerLink="/other">Other</a> <a routerLink="/other3">Other3</a> </h1>
一切都是通过角-cli(例如:n组分XXX)生成的.是的,CanDeactivate保护将始终返回false,这样您就无法卸载主组件。所以,当我第一次点击其他的时候,警卫就会被叫来。如果再次单击“其他”,则不会调用任何守卫。但是,如果我单击other3,则会调用守卫。点击other3不会真正做任何事情,直到我点击其他链接(例如:其他).
这是预期的行为吗?我必须说,每次我碰到另一个链接时,我的警卫都会被击中.
谢谢。
路易斯
发布于 2016-12-14 22:34:44
该死,bug...Note to self:下次,先检查问题板
https://github.com/angular/angular/issues/12851#event-880719778
发布于 2017-04-19 10:39:42
我找到了这个解决方案,而不是为每个组件创建一个candeactivate保护,您将创建一个保护服务,并向每个要添加此选项的组件中添加candeactivate方法,所以首先您必须添加这个服务文件“deactivate d.service.ts”:
import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
import { Observable } from 'rxjs/Observable';
export interface CanComponentDeactivate {
canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
}
@Injectable()
export class DeactivateGuardService implements CanDeactivate<CanComponentDeactivate>{
canDeactivate(component: CanComponentDeactivate) {
return component.canDeactivate ? component.canDeactivate() : true;
}
}然后您必须在应用程序模块中提供:
providers: [
DeactivateGuardService
]现在,在您要保护的组件中,添加以下函数:
export class ExampleComponent {
loading: boolean = false;
//some behaviour that change the loading value
canDeactivate() {
console.log('i am navigating away');
if (this.loading) {
console.log('no, you wont navigate anywhere');
return false;
}
console.log('you are going away, goodby');
return true;
}
}可以看到,变量加载是组件的本地加载。最后一步是将指令添加到路由模块中的组件中:
{
path: 'example',
canDeactivate: [DeactivateGuardService],
component: ExampleComponent
}就这样,我希望这是有帮助的,古德勒克。
https://stackoverflow.com/questions/41148020
复制相似问题