Lien passif dans Angular 2 - équivalent <a href=?">


140

Dans Angular 1.x, je peux faire ce qui suit pour créer un lien qui ne fait pratiquement rien:

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

Mais la même balise navigue vers la base de l'application dans Angular 2. Quel est l'équivalent de cela dans Angular 2?

Edit: Cela ressemble à un bogue dans le routeur Angular 2 et il y a maintenant un problème ouvert sur github à ce sujet.

Je recherche une solution prête à l'emploi ou une confirmation qu'il n'y en aura pas.


Vous pouvez toujours. C'est juste du html. Une utilisation particulière pour cela?
Sasxa

Oui, c'est toujours du html valide, mais l'effet n'est pas le même avec Angular 1.x.
s.alem

1
Avez-vous essayé juste <a>, sans "html"?
Sasxa

3
Ouais, mais le navigateur ne le traite pas de la même manière. Je sais que je peux remplacer l'effet de curseur avec css et attribuer un pointeur à toutes les abalises. Mais cela semble piraté.
s.alem

3
Mon opinion est que ng1 était la mauvaise façon (: le comportement par défaut devrait être comme il est dans le html standard ...
Sasxa

Réponses:


187

Si vous avez Angular 5 ou plus, changez simplement

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

dans

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

Un lien sera affiché avec une icône en forme de main lorsque vous le survolerez et que cliquer dessus ne déclenchera aucun itinéraire.

Remarque: si vous souhaitez conserver les paramètres de requête, vous devez définir l' queryParamsHandlingoption sur preserve:

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

2
Cela a fonctionné, [routerLink]=""il est rendu comme <a href="null" (click)="myFunction()">My Link</a>Angular 5 dans Chrome 64.
Zymotik

3
Je peux confirmer la même chose [routerLink]=""/ href="null"travaille dans IE 11
Zymotik

1
<a [routerLink </font>="" (click)="passTheSalt()"> Click me </a> fonctionne dans angular7. Je vois que <a (click)="passTheSalt()"> Cliquez sur moi </a> sans routerLInk fonctionne également dans angular7. quelle est la meilleure façon de créer un lien d'ancrage passif en utilisant [routerLink] ou pas de routerLink?
Ian Poston Framer

1
@IanPostonFramer Lorsque je supprime [routerLink]="", le texte Cliquez sur moi n'est pas affiché sous forme de lien et n'affiche pas l'icône du curseur de la main.
Emiel Koning

5
AVIS: cela réinitialisera vos paramètres d'URL. méfiez-vous de l'acheteur.
Stavm

88

Ce sera la même chose, cela n'a rien de lié angular2. C'est une simple balise HTML.

Fondamentalement, la abalise (d'ancrage) sera rendue par un analyseur HTML.

Éditer

Vous pouvez désactiver cela hrefen ayant javascript:void(0)dessus pour que rien ne se passe dessus. (Mais son hack). Je sais qu'Angular 1 a fourni cette fonctionnalité hors de la boîte qui ne me semble pas correcte maintenant.

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

Plunkr


Une autre solution pourrait être d'utiliser une routerLinkdirective avec une ""valeur de passage qui finira par générer un blanchref=""

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

@ s.alem quoi que vous disiez, que le fait d'avoir un #ancrage à l'intérieur hrefpeut affecter la Angular1route..peut vous envoyer à la page par défaut (si c'est là)
Pankaj Parkar

1
Je connais l'effet de #dans angulaire 1.x. Je veux un lien qui ne fait rien dans angular2, tout comme href=""dans angular 1.x.
s.alem

@ s.alem le <a href="">My Link</a>fera donc..mais que se passe-t-il actuellement?
Pankaj Parkar

1
[routerLink] = "" supprimera les paramètres de requête de votre itinéraire, ce n'est probablement pas ce que vous voulez. Vous pouvez utiliser des paramètres de requête de conservation, mais cela semble aller trop loin
narthur157

2
Cependant, l'option 1: href="javascript:void(0);"fonctionne pour moi.
Paul Carlton le

21

Il existe des moyens de le faire avec angular2, mais je ne suis pas du tout d'accord pour dire qu'il s'agit d'un bug. Je ne suis pas familiarisé avec angular1, mais cela semble être un comportement vraiment erroné même si, comme vous le prétendez, il est utile dans certains cas, mais il est clair que cela ne devrait pas être le comportement par défaut de tout framework.

Mis à part les désaccords, vous pouvez écrire une directive simple qui saisit tous vos liens et vérifier hrefle contenu de et si la longueur de celui-ci est de 0 que vous exécutez preventDefault(), voici un petit exemple.

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

Vous pouvez le faire fonctionner dans toute votre application en ajoutant cette directive dans PLATFORM_DIRECTIVES

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

Voici un plnkr avec un exemple de travail.


Voter pour une solution globale et angulaire, mais je ne l'accepte pas comme la bonne réponse car, comme je l'ai dit, je recherche uniquement une solution de sortie, jusqu'à ce qu'ils confirment qu'il n'y en aura pas ou que j'en ai vraiment besoin. il. Mais encore merci beaucoup.
s.alem

2
Le problème avec pointer-eventsc'est le manque de support avec IE ( caniuse ) (je peux le contourner même avec IE11 assez bizarrement), et cela n'empêche pas de cliquer sur le lien depuis la console. J'ai voté pour la réponse @Pankaj parce que c'est la plus simple de mon point de vue, ma réponse est juste un moyen de le faire avec angular2, je pourrais le rendre plus facile mais les sélecteurs css sont limités.
Eric Martinez

1
Cela semble rompre les liens des onglets d'amorçage (tels que <a href="#tab-id">)
xd6_

Dans quel module est la fonction bootstrap?
711

16

Un achor devrait naviguer vers quelque chose, donc je suppose que le comportement est correct lorsqu'il achemine. Si vous en avez besoin pour basculer quelque chose sur la page, c'est plus comme un bouton? J'utilise bootstrap pour pouvoir utiliser ceci:

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

1
J'aime cette solution. Si vous voulez que le curseur montre une main, ajoutez style = "cursor: pointer".
newman

Dans de nombreuses situations, une bonne solution, mais sachez que le bouton a des dimensions plus grandes que le simple point d'ancrage basé sur du texte.
yankee

@yankee vous pouvez changer cela en css, mais je ne recommande pas ... le fait est qu'un bouton est un bouton, et un lien est un lien ... trop triste le Web n'est pas si blanc ou noir.
Ayyash

11

J'utilise cette solution de contournement avec 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>

J'espère que cela t'aides


1
C'est une meilleure solution car c'est principalement un effet visuel qui manque. Vous pouvez mettre ce CSS dans le styles.cssfichier de premier niveau du projet Angular et cela fonctionnera très bien!


5

Une solution très simple consiste à ne pas utiliser de balise A - utilisez plutôt un span:

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

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

Vous ne devriez pas faire cela dans le sens du balisage sématique. Utilisez un buttonélément au cas où vous le souhaiteriez doSomethingsur la page.
Michael Kühnel

<button>les éléments déclenchent le clic par défaut lorsque la spacetouche est enfoncée. L'utilisation de span(ou <a>) supprime cette fonctionnalité - les actions du clavier ne fonctionneront donc pas comme prévu
Drenai

4

Voici un moyen simple

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

capturer l'événement bouillonnant et l'abattre


Pourquoi ne pas utiliser l'ancre elle-même pour empêcher le comportement par défaut? Comme décrit ici: stackoverflow.com/a/44465069/702783 Cela me semble moins «piraté».
Michael Kühnel

4

Voici quelques moyens de le faire:

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

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

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


3

Dans mon cas, la suppression de l'attribut href résout le problème tant qu'il y a une fonction de clic assignée à un.


3

Vous avez empêché le comportement par défaut du navigateur. Mais vous n'avez pas besoin de créer une directive pour y parvenir.

C'est simple comme l'exemple suivant:

my.component.html

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

my.component.ts

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

3

Mis à jour pour 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

J'ai 4 solutions pour la balise d'ancrage factice.

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

4. Si vous utilisez bootstrap:

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

0

Je me demande pourquoi personne ne suggère routerLink et routerLinkActive (Angular 7)

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

J'ai supprimé le href et je l'utilise maintenant. Lors de l'utilisation de href, il allait à l'URL de base ou rechargeait à nouveau la même route.


0

vous devez empêcher le comportement par défaut de l'événement comme suit.

En html

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

Dans le fichier ts

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

-1

Mis à jour pour 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();
        }
    }
}

En utilisant

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

-1

La solution vraiment simple est (click)="(null)"

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


peut-être un commentaire pourquoi une telle technique est mauvaise?
grigson

1
Écrire un clic partout dans le code lorsque vous ne voulez pas qu'un clic est mauvais
Jens Alenius

2
mais c'est exactement ce que je veux faire: marquer la place dans le code comme "rien au clic" capable, mais supporte une nouvelle syntaxe. Les constructions comme onclick = "javascript: void" sont vraiment laides. Et href = "#" ne sont pas fiables, car ils peuvent faire passer votre fenêtre en haut. Donc je ne peux pas voir de meilleures alternatives
grigson

J'aime ta solution. Je vous remercie.
Mai Hữu Lợi

Vérifiez ma nouvelle réponse. Si vous ne voulez pas que l'achor navigue, c'est un bouton 'type'
Jens Alenius
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.