Link pasywny w Angular 2 - odpowiednik <a href=etooth”>


140

W Angular 1.x mogę wykonać następujące czynności, aby utworzyć łącze, które w zasadzie nic nie robi:

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

Ale ten sam znacznik przechodzi do bazy aplikacji w Angular 2. Jaki jest odpowiednik tego w Angular 2?

Edycja: Wygląda na błąd w routerze Angular 2, a teraz jest otwarty problem na ten temat na githubie .

Szukam rozwiązania po wyjęciu z pudełka lub potwierdzenia, że ​​nie będzie.


Nadal możesz. To tylko html. Jakieś szczególne zastosowanie?
Sasxa

Tak, nadal jest to poprawny html, ale efekt nie jest taki sam w przypadku Angular 1.x.
s.alem

1
Czy próbowałeś po prostu <a>bez „html”?
Sasxa,

3
Tak, ale przeglądarka nie traktuje tego w ten sam sposób. Wiem, że mogę przesłonić np. Efekt kursora za pomocą css i przypisać wskaźnik do wszystkich atagów. Ale to wygląda na zepsute.
s.alem

3
Moja opinia jest taka, NG1 sposób był niewłaściwy sposób (: Domyślne zachowanie powinno być, jak to jest w standardzie HTML ...
Sasxa

Odpowiedzi:


187

Jeśli masz Angular 5 lub nowszy, po prostu zmień

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

w

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

Łącze zostanie wyświetlone z ikoną dłoni, gdy najedziesz na nie kursorem, a kliknięcie go nie uruchomi żadnej trasy.

Uwaga: Jeśli chcesz zachować parametry zapytania, ustaw queryParamsHandlingopcję na preserve:

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

2
To zadziałało [routerLink]="", renderuje jako <a href="null" (click)="myFunction()">My Link</a>Angular 5 w Chrome 64.
Zymotik

3
Potwierdzam to samo [routerLink]=""/ href="null"działa w IE 11
Zymotik

1
<a [routerLink]="" (click)="passTheSalt()"> Kliknij mnie </a> działa w angular7. Widzę, że <a (click)="passTheSalt()"> Kliknij mnie </a> bez routera Ink działa również w angular7. jaki jest lepszy sposób na utworzenie pasywnego łącza zakotwiczenia przy użyciu [routerLink] lub bez routerLink?
Ian Poston Framer

1
@IanPostonFramer Po usunięciu [routerLink]=""tekstu Kliknij mnie nie jest wyświetlany jako łącze i nie pokazuje ikony kursora dłoni.
Emiel Koning

5
UWAGA: spowoduje to zresetowanie parametrów adresu URL. kupujący uważaj.
Stavm

88

To będzie to samo, nie ma z tym nic związanego angular2. To prosty tag html.

Zasadniczo atag (kotwica) będzie renderowany przez parser HTML.

Edytować

Możesz to wyłączyć, hrefmając javascript:void(0)na nim, aby nic się z nim nie działo. (Ale to hack). Wiem, że Angular 1 dostarczył tę funkcję od razu po wyjęciu z pudełka, co nie wydaje mi się teraz poprawne.

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

Plunkr


Inaczej można by użyć routerLinkdyrektywy z przekazaniem ""wartości, która ostatecznie wygeneruje wartość pustąhref=""

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

@ s.alem cokolwiek mówisz, że posiadanie #kotwicy wewnętrznej hrefmoże wpłynąć na Angular1trasę .. może wysłać do strony domyślnej (jeśli jest)
Pankaj Parkar

1
Znam efekt #w kątowym 1.x. Chcę łącza, które nic nie robi w angular2, tak jak href=""w angular 1.x.
s.alem

@ s.alem, więc <a href="">My Link</a>to zrobię ... ale co się z tym obecnie dzieje?
Pankaj Parkar

1
[routerLink] = "" usunie parametry zapytania z twojej trasy, prawdopodobnie nie tego chcesz. Możesz użyć zachowania parametrów zapytania, ale wydaje się, że to zbyt daleko
idące

2
Jednak opcja 1: href="javascript:void(0);"DZIAŁA dla mnie.
Paul Carlton,

21

Istnieją sposoby na zrobienie tego z angular2, ale zdecydowanie nie zgadzam się, że jest to błąd. Nie jestem zaznajomiony z angular1, ale wydaje mi się, że jest to naprawdę niewłaściwe zachowanie, mimo że według Ciebie jest przydatne w niektórych przypadkach, ale wyraźnie nie powinno to być domyślne zachowanie żadnego frameworka.

Pomijając nieporozumienia, możesz napisać prostą dyrektywę, która pobierze wszystkie linki i sprawdzi hrefich zawartość, a jeśli jej długość wynosi 0, wykonujesz ją preventDefault(), oto mały przykład.

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

Możesz sprawić, że będzie działać w całej aplikacji, dodając tę ​​dyrektywę w PLATFORM_DIRECTIVES

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

Oto plnkr z działającym przykładem.


Głosuj za globalnym, kątowym rozwiązaniem, ale nie akceptuję tego jako poprawnej odpowiedzi, ponieważ jak powiedziałem, szukam tylko rozwiązania outbox, dopóki nie potwierdzą, że nie będzie żadnego lub dopóki naprawdę nie potrzebuję to. Ale nadal bardzo dziękuję.
s.alem

2
Problemem pointer-eventsjest brak wsparcia z IE ( caniuse ) (nawet z IE11 mogę to ominąć) i nie przeszkadza to w kliknięciu linku z konsoli. Głosowałem za odpowiedzią @Pankaj, ponieważ jest najłatwiejsza z mojego punktu widzenia, moja odpowiedź jest po prostu sposobem na zrobienie tego z angular2, mógłbym to ułatwić, ale selektory css są ograniczone.
Eric Martinez

1
Wydaje się, że powoduje to zerwanie linków do zakładek bootstrap (takich jak <a href="#tab-id">)
xd6_

W którym module jest funkcja bootstrap?
Jun711

16

Achor powinien prowadzić do czegoś, więc wydaje mi się, że zachowanie jest prawidłowe, gdy kieruje. Jeśli potrzebujesz go do przełączania czegoś na stronie, to bardziej przypomina przycisk? Używam bootstrap, więc mogę użyć tego:

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

1
Podoba mi się to rozwiązanie. Jeśli chcesz, aby kursor pokazywał dłoń, dodaj style = "cursor: pointer".
newman

W wielu sytuacjach jest to dobre rozwiązanie, jednak należy pamiętać, że przycisk ma większe wymiary niż tylko kotwica oparta na tekście.
yankee

@yankee możesz to zmienić w css, ale nie polecam ... Fakt jest taki, że przycisk to przycisk, a link to link ... Szkoda, że ​​sieć nie jest taka biała ani czarna.
Ayyash

11

Używam tego obejścia z 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>

Mam nadzieję że to pomoże


1
To lepsze rozwiązanie, ponieważ brakuje głównie efektu wizualnego. Możesz umieścić ten CSS w styles.csspliku najwyższego poziomu projektu Angular i będzie działać świetnie!


5

Naprawdę prostym rozwiązaniem nie jest użycie tagu A - zamiast tego użyj span:

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

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

Nie powinieneś tego robić w sensie znaczników sematycznych. Użyj buttonelementu, jeśli chcesz doSomethingna stronie.
Michael Kühnel

<button>elementy uruchamiają kliknięcie domyślnie po spacenaciśnięciu klawisza. Użycie span(lub <a>) usuwa tę funkcję - więc działania klawiatury nie będą działać zgodnie z oczekiwaniami
Drenai


4

Oto kilka sposobów, aby to zrobić:

  • <a href="" (click)="false">Click Me</a>

  • <a style="cursor: pointer;">Click Me</a>

  • <a href="javascript:void(0)">Click Me</a>


3

W moim przypadku usunięcie atrybutu href rozwiązuje problem, o ile istnieje przypisana funkcja kliknięcia do pliku.


3

Zablokowałeś domyślne zachowanie przeglądarki. Ale nie musisz tworzyć dyrektywy, aby to osiągnąć.

Jest to proste, jak na poniższym przykładzie:

my.component.html

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

my.component.ts

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

3

Zaktualizowano dla 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();
    }
  }
}

3

Mam 4 rozwiązania dla atrapy zawieszki.

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

4. Jeśli używasz bootstrap:

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

0

Zastanawiam się, dlaczego nikt nie sugeruje routerLink i routerLinkActive (Angular 7)

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

Usunąłem href i teraz używam tego. Podczas korzystania z href powodowało to przechodzenie do podstawowego adresu URL lub ponowne ładowanie tej samej trasy.


0

musisz zapobiec domyślnemu zachowaniu zdarzenia w następujący sposób.

W html

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

W pliku ts

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

-1

Zaktualizowano dla 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();
        }
    }
}

Za pomocą

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

-1

Naprawdę prostym rozwiązaniem jest (click)="(null)"

<a class="btn btn-default" (click)="(null)">Default</a>


może jakiś komentarz dlaczego taka technika jest zła?
grigson

1
Pisanie kliknięcia wszędzie w kodzie, gdy nie chcesz, aby kliknięcie było złe
Jens Alenius

2
ale to jest dokładnie to, co chcę zrobić: oznacz miejsce w kodzie jako „nic nie można kliknąć”, ale obsługuję nową składnię. Konstrukcje takie jak onclick = "javascript: void" są naprawdę brzydkie. A href = "#" są zawodne, ponieważ mogą przeskoczyć twój widoczny obszar na górę. Więc nie widzę lepszych alternatyw
Grigson

Podoba mi się twoje rozwiązanie. Dziękuję Ci.
Mai Hữu Lợi

Sprawdź moją nową odpowiedź. Jeśli nie chcesz, aby achor nawigował, jego przycisk
``
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.