简体   繁体   中英

How can I conditionally disable the routerLink attribute?

In my Angular 2 application I'm trying to disable a routerLink without any success. I've tried to handle the click event on the click event (with event.preventDefault() and event.stopPropagation() ) but it doesn't work.

How can I disable a routerLink?

Disable pointer-events on the element via CSS:

<a [routerlink]="xxx" [class.disabled]="disabled ? true : null">Link</a>

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

See also Angular2, what is the correct way to disable an anchor element?

or

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

or to easily reuse the disabled link template

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

No need to disable any pointer events:

Template:

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

Optional CSS:

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

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

Live demo:
See demo on StackBlitz

Description:

When linkEnabled returns false , null will make routerLink to link to the current/active route.

If routerLink links to the active route, the class which is specified in routerLinkActive will be applied. That will be is_disabled in this case.

There we can specify, how the disabled routerLink should appear.

routerLink to the active route won't trigger a navigation event.

Disabling pointer-events on any html tag:

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

'none' resolves to disabling pointer-events , that is, disabling the link.

null resolves to ignore the style.

I've just had some success with a similar issue: having an array of nav links in an ngFor, some required [routerLink], while others required (click) - my issue was that all links relied on [routerLink] for [routerLinkActive], so I had to stop routerLink, without touching it's value.

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

with:

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

As the span is inside, you can be sure the cancelling of the event happens before it bubbles up to [routerLink], while routerLinkActive will still apply.

Unfortunately, Angular doesn't seem to have a null value support for the routerLink .

However, this works for me. An example of my menu implementation:

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

Simply put, if a category has any subcategories, don't redirect, but open the subcategories.

You can decide whether the routerLink directive is rendered based on a condition.

In the template:

<a [attr.routerLink]="isDisabled ? null : ''"></a>

When the value is null , the routerLink directive will not be rendered on the element.

In your component file:

get isDisabled() {
 return ... // logic for when the routerLink should be disabled
}

All the top answer are workaround.

The best way is something you can find in this solution https://stackoverflow.com/a/45323200/3241192 by @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>

Try this:

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

My case was to use routerLink, sometimes use click to open modal, and internal logic of route URL if we don't provide routerLink URL. So for click, I had to delete routerLink.

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

in my case, null deletes routerLink attribute, and I can use (click) event properly.

PS empty array [] provided in answers abowe doesn't remove attribute routerlink from the element.

Disable click based on condition using following simple CSS

.disable-anchor { 
  pointer-events: none; 
}

<a [routerlink]="link" [ngClass]="{'disable-anchor' : condition}">Link</a>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM