gpt4 book ai didi

angular - 如果无法激活其关联路由,则隐藏 routerLink?

转载 作者:太空狗 更新时间:2023-10-29 17:50:35 31 4
gpt4 key购买 nike

我有:

  • 与 routerLinks 的链接
  • 指向具有 canActivate 逻辑的路由
  • canActivateLogic根据目标组件和用户权限授权或不授权

我想用无法激活的 routerLinks 隐藏链接。

有什么好的方法可以隐藏无法激活的 routerLink 吗?

现在你会说做一些像“分享 canActivate 逻辑”这样的事情:

<a [hidden]="callThatCanActivateLogic()" [routerLink]="['/brand']"

问题是这个 canActivateLogic 依赖于组件和权限,这将被错误地设计为以下内容,因为组件解析应该委托(delegate)给路由,而不是嵌入到链接中:

<a [hidden]="callThatCanActivateLogic(TheComponentAtTheEndTargettedByTheRoute, IAmInThatContext)" [routerLink]="['/brand']"

如果有一个解决方案可以在 routerLink 和它的路由 canActivate 之间提供链接,那就太幸运了:)

最佳答案

今天我遇到了同样的问题。不幸的是,我没有找到任何好的解决方案,所以我不得不自己创建一个。

想法是创建一个指令,它将路由器路径作为参数,如果不允许转换则隐藏链接。例如:

<li [allowTransition]="'list'">
<a routerLink="list">List</a>
</li>

指令的逻辑如下:

1) 导入所有路由器的配置,并从属性中找到具有输入路径的配置。我的配置如下:

  { path: 'login', component: LoginComponent },
{ path: 'list', component: ListComponent, canActivate: [UserGuardService]},

2)然后指令读取配置的canActivate属性,通过注入(inject)器获取UserGuardService。通过这种方式,指令采用 UserGuardService 的实例。 UserGuardService 是实现 CanActivate 接口(interface)的类。

3)UserGuardService 知道转换是否被允许。所以我们应该询问它并通过更改 css 显示属性来处理答案。

但是有两个特性对实现有很大的影响:

A) CanActivate 接口(interface)不太舒服,因为要调用它我们必须创建 ActivatedRouteSnapshot 和 RouterStateSnapshot 对象。真正的过渡可能是必要的,但在这种情况下,我们只想知道过渡是否可能。

B) 我们应该在某些事件(在我的例子中是登录事件)之后提供链接可见性刷新

为了解决问题 A,我创建了接口(interface) Guard。

export interface Guard {
allowTransition():boolean;
}

所以,我希望我所有的 CanActivate 实现也实现 Guard 接口(interface)。现在我典型的 CanActivate 实现看起来像这样:

canActivate(route:ActivatedRouteSnapshot,
state:RouterStateSnapshot):Observable<boolean>|boolean {
//this method performs only "naigation" logic. It calls another method for business logic.
var allow = this.allowTransition();
if (!allow) {
this.router.navigate(['login']);
}
return allow;
}

allowTransition():boolean {
// this method contains business logic of transition possibility
return this.userService.hasCurrentUserRole("USER");
}

在这样的“接口(interface)划分”之后,我可以从我的指令中调用简单的方法 allowTransition()。代码如下。

import {routes} from "../../../app.routes";
... other imports
@Directive({selector: '[allowTransition]'})
export class AllowTransition implements OnDestroy, LoginListener, OnInit {

private el: HTMLElement;

private visibleDisplay:string;

@Input('allowTransition') destUrl: string;

constructor(el: ElementRef, private injector: Injector,
@Inject('appUserService') private userService : UserService ) {
this.el = el.nativeElement;
this.visibleDisplay = this.el.style.display;
}

ngOnDestroy() {
this.userService.removeLoginListener(this)
}


ngOnInit() {
this.userService.addLoginListener(this);
this.onLogin();
}

onLogin() {
let allow = true;

for (let i = 0; i < routes.length; i++) {
let path = routes[i].path;
if (path == this.destUrl) {
let canActivate = routes[i].canActivate;
if (canActivate != null) {
//todo do the same for canActivate[i]
try {
let canActivateInstance = this.injector.get(canActivate[0]) as Guard;
allow = canActivateInstance.allowTransition();
} catch (error) {
//did you forget to implement Guard?
console.error('Error');
}
}
}
}
this.el.style.display = allow ? this.visibleDisplay : 'none';
}
}

我在上面提到了问题 B,这就是为什么我的指令使用一种方法 onLogin() 实现 LoginListener 接口(interface)。虽然该指令存在,但它应该在事件生产者处注册并在发生变化时进行处理。在我的例子中,登录或注销后 UserService 调用所有指令的方法 onLogin() 并且每个链接都刷新。

初始显示属性也可以有多个值,这就是指令必须将其保留为“visibleDisplay”属性的原因。

作为结论,现在可以在没有任何关于与路由对应的组件的信息的情况下使用该指令。这种方法的主要缺点是它不适用于像“view/:id”这样的动态路由。也不允许在 CanActivate 方法中使用 Observale 而不是 bool 值。当然,可以修复它,但在我看来,我这样做的方式对于这么简单的事情来说已经太复杂了。我刚刚完成了我需要的所有工作,等待具有类似功能的 angular2 更新。

更多信息:https://kosbr.github.io/2016/10/18/angular2-guard-router.html

关于angular - 如果无法激活其关联路由,则隐藏 routerLink?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38976109/

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