如何有条件地禁用 routerLink 属性?

How can I conditionally disable the routerLink attribute?

在我的 Angular 2 应用程序中,我试图禁用 routerLink 但没有成功。我试图处理 click 事件(使用 event.preventDefault()event.stopPropagation())的点击事件,但它不起作用。

如何禁用 routerLink?

通过 CSS:

在元素上禁用 pointer-events
<a [routerlink]="xxx" [class.disabled]="disabled ? true : null">Link</a>

a.disabled {
   pointer-events: none;
   cursor: default;
}

另见

<a *ngIf="isEnabled" [routerlink]="xxx">Link</a>
<div *ngIf="!isEnabled">not a link</div>

或轻松重用禁用的 link 模板

<ng-template #disabledLink>
  <div *ngIf="!isEnabled">not a link</div>
</ng-template>
<a *ngIf="isEnabled; else disabledLink" [routerLink]="xxx">Link</a>

Angular 13岁及以上

[routerLink]="null"(和undefined)现在正式用于禁用routerLink
(参见 Docs

所以这就足够了:

<a [routerLink]="linkEnabled ? 'path' : null">Link</a>

Angular 12岁及以下

[routerLink]="null"(和 undefined)被视为空命令数组的 shorthand。所以它使 routerLink 到 link 到 current/active 路线。这种行为允许我们为了我们的目的滥用 routerLinkActive 指令:

模板:

<a [routerLink]="linkEnabled ? 'path' : null"
   [routerLinkActive]="linkEnabled ? 'is_active' : 'is_disabled'">Link</a>

可选CSS:

.is_disabled {
    cursor: default;
    text-decoration: none;
}

.is_active {
    // your style for active router link
}

现场演示 (Angular 10):
See demo on StackBlitz

详细说明:

linkEnabled returns false时,nullrouterLink到link到current/active路线。

如果 routerLink link 到活动路线,将应用 routerLinkActive 中指定的 class。在本例中为 is_disabled

在那里我们可以指定禁用的 routerLink 应该如何显示。

routerLink到活动路线不会触发导航事件。

我刚刚在类似问题上取得了一些成功:在 ngFor 中有一组导航链接,一些需要 [routerLink],而另一些需要(单击)- 我的问题是所有链接都依赖于 [routerLink ] 对于 [routerLinkActive],所以我不得不停止 routerLink,而不触及它的价值。

`<a [routerLink]="item.link" routerLinkActive="isActive">
    <span (click)="item.click ? item.click($event) : void>
</a>`

与:

`click: ($event) => {
    $event.stopPropagation(); // Only seems to
    $event.preventDefault(); // work with both
    // Custom onClick logic
}`

由于跨度在内部,您可以确定事件的取消发生在它冒泡到 [routerLink] 之前,而 routerLinkActive 仍然适用。

任何 html 标签上禁用 pointer-events

<div [routerLink]="['/home', { foo: bar }]"
     [ngStyle]="{'pointer-events': myLinkEnabled ? 'none' : null}">
     Click me
</div>

'none'解析为禁用pointer-events,即禁用link.

null 决定忽略样式。

不幸的是,Angular 似乎没有对 routerLinknull 值支持。

但是,这对我有用。我的菜单实现示例:

<div *ngFor="let category of categories" [routerLink]="category.subcategories ? [] : [category.link]" (click)="toggleSubcategories(category)">

简单地说,如果一个类别有子类别,不要重定向,而是打开子类别。

试试这个:

<div *ngFor="let childitem of menuitem.MenuRoutes">
<a [routerLink]="menuitem.IsMain ? [childitem.Route] : []"><a>
</>

所有最佳答案都是解决方法。

最好的方法是您可以在@taras-d

的解决方案 中找到

Another way to disable routerLink - replace onClick method.

To do this you have to create directive:

import { Directive, Input, Optional } from '@angular/core';
import { RouterLink, RouterLinkWithHref } from '@angular/router';

@Directive({
    selector: '[routerLink][disableLink]'
})
export class DisableLinkDirective {

    @Input() disableLink: boolean;

    constructor(
        // Inject routerLink
        @Optional() routerLink: RouterLink,
        @Optional() routerLinkWithHref: RouterLinkWithHref
    ) {

        const link =  routerLink || routerLinkWithHref;

        // Save original method
        const onClick = link.onClick;

        // Replace method
        link.onClick = (...args) => {
            if (this.disableLink) {
                return routerLinkWithHref? false: true;
            } else {
                return onClick.apply(link, args);
            }
        };
    }

}

Usage:

<a routerLink="/search" [disableLink]="!isLogged">Search</a>

我的情况是使用routerLink,如果我们不提供routerLink URL,有时会使用点击打开模式,以及路由URL 的内部逻辑。所以为了点击,我不得不删除 routerLink。

[routerLink]="disableRouterLink ? null : (btnRouterLink || pathCondition)"

在我的例子中,null 删除了 routerLink 属性,我可以正常使用 (click) 事件。

P.S。答案中提供的空数组 [] 不会从元素中删除属性 routerlink。