gpt4 book ai didi

Angular 2 : CanDeactivate guard

转载 作者:太空狗 更新时间:2023-10-29 16:59:28 25 4
gpt4 key购买 nike

我创建了一个 CanDeactivate 守卫,它返回一个 observable,并将其应用于一个加载到内部嵌套路由器导出中的组件。每当有人试图导航到另一个 url 时,是否应该调用这个守卫?我问这个是因为我的情况没有发生。

在我的例子中,守卫只会在第一个“不同的”URL 时被调用。让我试着用一个例子来解释它。假设我总是返回 false 并且我正在尝试从同一组件导航到不同的 url:

/A --> guard called
/B --> guard called
/B --> no navigation and no guard called
/A --> guard called
/A -->guard not called and no navigation

这是预期的行为吗?

edit 嗯,好像是这样。刚刚构建了一个包含 3 个组件的小示例,并且只会在用户第一次尝试导航到特定 url 时调用守卫...这真的很奇怪...

无论如何,这是我正在使用的代码:

// 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>

一切都是通过 angular-cli 生成的(例如:n g component XXX)。是的,CanDeactivate 守卫将始终返回 false,因此您将无法卸载主要组件。所以,我第一次点击其他时, guard 被召唤。如果再次单击其他,则不会调用守卫。但是,如果我点击 other3,就会调用守卫。在我点击其他链接(例如:其他)之前,点击 other3 不会真正做任何事情......

这是预期的行为吗?我必须说,每次我点击另一个链接时,我都希望我的守卫被击中......

谢谢。

路易斯

最佳答案

我已经找到了这个解决方案,而不是为每个组件创建一个 candeactivate 守卫,你将创建一个守卫服务并为你想要添加这个选项的每个组件添加一个 candeactivate 方法,所以首先你必须添加这个服务文件“停用-guard.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
}

就是这样,我希望这对您有所帮助,祝您好运。

关于 Angular 2 : CanDeactivate guard,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41148020/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com