ChatGPT解决这个技术问题 Extra ChatGPT

Passive Link in Angular 2 - <a href=""> equivalent

In Angular 1.x I can do the following to create a link which does basically nothing:

<a href="">My Link</a>

But the same tag navigates to the app base in Angular 2. What is the equivalent of that in Angular 2?

Edit: It looks like a bug in the Angular 2 Router and now there is an open issue on github about that.

I am looking for an out of the box solution or a confirmation that there won't be any.

You still can. It's just html. Any particular use for it?
Yes, it is still valid html, but the effect is not the same with Angular 1.x.
Did you try just <a>, without "html"?
Yeah, but than the browser doesn't treat it in the same way. I know I can override i.e. the cursor effect with css, and assign pointer to all a tags. But that looks hacky.
My opinion is that ng1 way was the wrong way (: Default behavior should be as it is in standard html...

s
s.alem

If you have Angular 5 or above, just change

<a href="" (click)="passTheSalt()">Click me</a>

into

<a [routerLink]="" (click)="passTheSalt()">Click me</a>

A link will be displayed with a hand icon when hovering over it and clicking it won't trigger any route.

Note: If you want to keep the query parameters, you should set queryParamsHandling option to preserve:

<a [routerLink]=""
   queryParamsHandling="preserve"
   (click)="passTheSalt()">Click me</a>

This worked [routerLink]="" it renders as <a href="null" (click)="myFunction()">My Link</a> Angular 5 in Chrome 64.
I can confirm the same [routerLink]="" / href="null" is working in IE 11
Click me works in angular7. I see Click me without routerLInk works in angular7 as well. what is better way to make a passive anchor link using [routerLink] or no routerLink?
@IanPostonFramer When I remove [routerLink]="", the text Click me is not displayed as a link and does not show hand cursor icon.
NOTICE: this will reset your URL params. buyer beware.
P
Pankaj Parkar

That will be same, it doesn't have anything related to angular2. It is simple html tag.

Basically a(anchor) tag will be rendered by HTML parser.

Edit

You can disable that href by having javascript:void(0) on it so nothing will happen on it. (But its hack). I know Angular 1 provided this functionality out of the box which isn't seems correct to me now.

<a href="javascript:void(0)" >Test</a>

Plunkr

Other way around could be using, routerLink directive with passing "" value which will eventually generate blank href=""

<a routerLink="" (click)="passTheSalt()">Click me</a>

@s.alem what ever you are saying, that having # inside anchor href can affect Angular1 route..may send you to default page(if its there)
I know the effect of # in angular 1.x. I want a link that does nothing in angular2, just like href="" in angular 1.x.
@s.alem so <a href="">My Link</a> will do that..but what happening currently with it?
[routerLink]="" will remove query params from your route, this is likely not what you want. You could use preserve query params, but this seems like going too far
However, option 1: href="javascript:void(0);" DOES work for me.
E
Eric Martinez

There are ways of doing it with angular2, but I strongly disagree this is a bug. I'm not familiarized with angular1, but this seems like a really wrong behavior even though as you claim is useful in some cases, but clearly this should not be the default behavior of any framework.

Disagreements aside you can write a simple directive that grabs all your links and check for href's content and if the length of it it's 0 you execute preventDefault(), here's a little example.

@Directive({
  selector : '[href]',
  host : {
    '(click)' : 'preventDefault($event)'
  }
})
class MyInhertLink {
  @Input() href;
  preventDefault(event) {
    if(this.href.length == 0) event.preventDefault();
  }
}

You can make it to work across your application by adding this directive in PLATFORM_DIRECTIVES

bootstrap(App, [provide(PLATFORM_DIRECTIVES, {useValue: MyInhertLink, multi: true})]);

Here's a plnkr with an example working.


Upvote for a global, angular solution, but I'm not accepting it as the correct answer because as I said, I'm only looking for an out box solution, until they confirm there won't be any or until I really really need it. But still thank you very much.
The problem with pointer-events is the lack of support with IE (caniuse) (I can bypass it even with IE11 weirdly enough), and it doesn't prevent to click the link from the console. I've upvoted @Pankaj answer because it's the easiest one from my point of view, my answer is just a way of doing it with angular2, I could make it easier but css selectors are limited.
This seems to break bootstrap tab links (such as )
Which module is bootstrap function in?
J
Jens Alenius

An achor should navigate to something, so I guess the behaviour is correct when it routes. If you need it to toggle something on the page it's more like a button? I use bootstrap so I can use this:

<button type="button" class="btn btn-link" (click)="doSomething()">My Link</button>

I like this solution. If you want to have cursor to show a hand, add style="cursor: pointer".
In many situations a good solution, however be aware that the button has bigger dimensions than just the text based anchor.
@yankee you can change that in css, but I don't recommend... fact is, a button is a button, and a link is a link... too sad the web is not that white or black.
S
Sabri Aziri

I am using this workaround with css:

/*** Angular 2 link without href ***/
a:not([href]){
    cursor: pointer; 
    -webkit-user-select: none; 
    -moz-user-select: none; 
    user-select: none
}

html

<a [routerLink]="/">My link</a>

Hope this helps


This is a better solution as it's mainly a visual effect that's missing. You can put this CSS in the Angular project's top-level styles.css file and it will work great!
a
ali-myousefi

simeyla solution:

<a href="#" (click)="foo(); false">
<a href="" (click)="false">

This appears to be the simplest and most elegant solution.
Simple answer 👍
just return false in the function, then you don't have to remember it in every tag you use the function.
S
Sal

Here are some ways to do it:

Click Me

Click Me

Click Me


M
Michael Kühnel

You have prevent the default browser behaviour. But you don’t need to create a directive to accomplish that.

It’s easy as the following example:

my.component.html

<a href="" (click)="goToPage(pageIndex, $event)">Link</a>

my.component.ts

goToPage(pageIndex, event) {
  event.preventDefault();
  console.log(pageIndex);
}

This will go over updates and doesn't deal with routerlink or null values.
b
born2net

Here is a simple way

  <div (click)="$event.preventDefault()">
            <a href="#"></a>
   </div>

capture the bubbling event and shoot it down


Why not use the anchor itself for preventing the default behavior? Like described here: stackoverflow.com/a/44465069/702783 Seems less »hacky« to me.
F
FiniteLooper

Updated for Angular 5

import { Directive, HostListener, Input } from '@angular/core';

@Directive({
  // tslint:disable-next-line:directive-selector
  selector : '[href]'
})
export class HrefDirective {
  @Input() public href: string | undefined;

  @HostListener('click', ['$event']) public onClick(event: Event): void {
    if (!this.href || this.href === '#' || (this.href && this.href.length === 0)) {
      event.preventDefault();
    }
  }
}

M
Michał Ignaszewski

In my case deleting href attribute solve problem as long there is a click function assign to a.


N
Nabin Kumar Khatiwada

I have 4 solutions for dummy anchor tag.

    1. <a style="cursor: pointer;"></a>
    2. <a href="javascript:void(0)" ></a>
    3. <a href="current_screen_path"></a>

4.If you are using bootstrap:

<button class="btn btn-link p-0" type="button" style="cursor: pointer"(click)="doSomething()">MY Link</button>

S
Shrike

Not sure why people suggest using routerLink="", for me in Angular 11 it triggers navigation. This is what works for me:

<div class="alert">No data yet, ready to <a href="#" (click)="create();$event.preventDefault()">create</a>?</div>

J
Jonathan

A really simple solution is not to use an A tag - use a span instead:

<span class='link' (click)="doSomething()">Click here</span>

span.link {
  color: blue;
  cursor: pointer;
  text-decoration: underline;
}

You shouldn’t do that in the sense of sematic markup. Use a button Element in case you want to doSomething on the page.
<button> elements trigger click by default when the space key is pressed. Using span (or <a>) removes this feature - so keyboard actions won't work as expected
yeah, i appreciate the solution but this breaks accessibility for many of us
This is never the right solution. Spans are meant for formatting text, anchors for linking, and navigation, Accessibility tools handle these differently.
U
U_R_Naveen UR_Naveen

you need to prevent event's default behaviour as follows.

In html

<a href="" (click)="view($event)">view</a>

In ts file

view(event:Event){
 event.preventDefault();
 //remaining code goes here..
}

M
Monster Brain

I wonder why no one is suggesting routerLink and routerLinkActive (Angular 7)

<a [routerLink]="[ '/resources' ]" routerLinkActive="currentUrl!='/resources'">

I removed the href and now using this. When using href, it was going to the base url or reloading the same route again.


g
geejay

Updated for Angular2 RC4:

import {HostListener, Directive, Input} from '@angular/core';

@Directive({
    selector: '[href]'
})
export class PreventDefaultLinkDirective {

    @Input() href;
    @HostListener('click', ['$event']) onClick(event) {this.preventDefault(event);}

    private preventDefault(event) {
        if (this.href.length === 0 || this.href === '#') {
            event.preventDefault();
        }
    }
}

Using

bootstrap(App, [provide(PLATFORM_DIRECTIVES, {useValue: PreventDefaultLinkDirective, multi: true})]);