Link passivo no Angular 2 - <a href=Produzido> equivalente


140

No Angular 1.x, posso fazer o seguinte para criar um link que basicamente não faz nada:

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

Mas a mesma tag navega para a base de aplicativos no Angular 2. Qual é o equivalente ao Angular 2?

Edit: Parece um bug no roteador Angular 2 e agora existe um problema em aberto no github sobre isso.

Estou procurando uma solução pronta para uso ou uma confirmação de que não haverá.


Você ainda pode. É apenas html. Algum uso particular para isso?
Sasxa

Sim, ainda é um html válido, mas o efeito não é o mesmo com o Angular 1.x.
s.alem

1
Você tentou apenas <a>, sem "html"?
Sasxa

3
Sim, mas o navegador não o trata da mesma maneira. Eu sei que posso substituir, ou seja, o efeito do cursor com css, e atribuir o ponteiro a todas as atags. Mas isso parece hacky.
s.alem

3
Minha opinião é de que maneira NG1 era o caminho errado (: O comportamento padrão deve ser como é em html padrão ...
Sasxa

Respostas:


187

Se você possui Angular 5 ou superior, basta alterar

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

para dentro

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

Um link será exibido com um ícone de mão ao passar o mouse sobre ele e clicar nele não acionará nenhuma rota.

Nota: Se você deseja manter os parâmetros da consulta, defina a queryParamsHandlingopção para preserve:

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

2
Isso funcionou [routerLink]=""torna como <a href="null" (click)="myFunction()">My Link</a>Angular 5 no Chrome 64.
Zymotik

3
Posso confirmar o mesmo [routerLink]=""/ href="null"está funcionando no IE 11
Zymotik

1
<a [routerLinkBody="" (click)="passTheSalt()"> Clique em mim </a> funciona em angular7. Eu vejo <a (click)="passTheSalt()"> Clique em mim </a> sem o routerLInk também funciona em angular7. Qual é a melhor maneira de criar um link âncora passivo usando [routerLink] ou nenhum routerLink?
precisa saber é o seguinte

1
@IanPostonFramer Quando removo [routerLink]="", o texto Clique em mim não é exibido como um link e não mostra o ícone do cursor de mão.
Emiel Koning

5
AVISO: isso redefinirá seus parâmetros de URL. comprador cuidado.
Stavm 22/09/19

88

Será o mesmo, não tem nada relacionado angular2. É simples tag html.

Basicamente, a amarca (âncora) será renderizada pelo analisador de HTML.

Editar

Você pode desativar esse hrefpor ter javascript:void(0)nele assim nada vai acontecer nele. (Mas é hack). Eu sei que o Angular 1 forneceu essa funcionalidade pronta para uso, o que não parece correto para mim agora.

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

Plunkr


Por outro lado, poderia estar usando routerLinkdiretiva com ""valor de passagem que acabará gerando espaço em brancohref=""

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

@ s.alem que sempre que você está dizendo, que ter #dentro âncora hrefpode afetar Angular1route..may enviar página padrão (se a sua existência)
Pankaj Parkar

Conheço o efeito do #angular 1.x. Eu quero um link que não faça nada no angular2, assim como href=""no angular 1.x.
s.alem

@ s.alem então <a href="">My Link</a>fará isso ... mas o que está acontecendo atualmente com ele?
Pankaj Parkar

1
[routerLink] = "" removerá os parâmetros de consulta do seu percurso, provavelmente não é o que você deseja. Você poderia usar preservar consulta params, mas esta parece ser ir longe demais
narthur157

2
No entanto, opção 1: href="javascript:void(0);"funciona para mim.
Paul Carlton

21

Existem maneiras de fazer isso com o angular2, mas eu discordo totalmente que isso é um bug. Não estou familiarizado com o angular1, mas isso parece um comportamento realmente errado, embora, como você alega, seja útil em alguns casos, mas claramente esse não deve ser o comportamento padrão de qualquer estrutura.

Discordâncias à parte, você pode escrever uma diretiva simples que agarre todos os seus links e verifique hrefo conteúdo de cada um. Se o comprimento for 0, você executará preventDefault(), aqui está um pequeno exemplo.

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

Você pode fazê-lo funcionar em seu aplicativo adicionando esta diretiva em PLATFORM_DIRECTIVES

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

Aqui está um plnkr com um exemplo de trabalho.


Voto positivo para uma solução angular global, mas não a aceito como a resposta correta, porque, como eu disse, só estou procurando uma solução pronta para uso, até que eles confirmem que não haverá nenhuma ou até que eu realmente precise isto. Mas ainda muito obrigado.
s.alem

2
O problema pointer-eventsé a falta de suporte com o IE ( caniuse ) (eu posso ignorá-lo mesmo com o IE11 por incrível que pareça), e isso não impede que você clique no link do console. Promovi uma resposta ao @Pankaj com voto positivo porque é a mais fácil do meu ponto de vista, minha resposta é apenas uma maneira de fazê-lo com angular2, eu poderia facilitar, mas os seletores de css são limitados.
Eric Martinez

1
Isso parece quebrar os links da guia de autoinicialização (como <a href="#tab-id">)
xd6_

Em qual módulo a função de auto-inicialização está?
Jun711

16

Um achor deve navegar para alguma coisa, então acho que o comportamento é correto quando é direcionado. Se você precisar alternar algo na página, é mais como um botão? Eu uso o bootstrap para poder usar isso:

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

1
Eu gosto desta solução. Se você deseja que o cursor mostre uma mão, adicione style = "cursor: ponteiro".
New17 de

Em muitas situações, uma boa solução, porém, esteja ciente de que o botão tem dimensões maiores do que apenas a âncora baseada em texto.
Yankee

@yankee você pode mudar isso em css, mas eu não recomendo ... o fato é que um botão é um botão e um link é um link ... muito triste a web não ser tão branca ou preta.
Ayyash

11

Estou usando esta solução alternativa com 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>

Espero que isto ajude


1
Esta é uma solução melhor, pois é principalmente um efeito visual que está faltando. Você pode colocar esse CSS no styles.cssarquivo de nível superior do projeto Angular e ele funcionará muito bem!


5

Uma solução realmente simples é não usar uma tag A - use uma extensão:

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

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

Você não deve fazer isso no sentido de marcação semática. Use um buttonelemento, se desejar doSomethingna página.
Michael Kühnel

<button>elementos acionam o clique por padrão quando a spacetecla é pressionada. Usando span(ou <a>) remove esse recurso - assim ações do teclado não vai funcionar como esperado
Drenai

4

Aqui está uma maneira simples

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

capturar o evento borbulhante e derrubá-lo


Por que não usar a própria âncora para impedir o comportamento padrão? Como descrito aqui: stackoverflow.com/a/44465069/702783 Parece menos »hacky« para mim.
Michael Kühnel

4

Aqui estão algumas maneiras de fazer isso:

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

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

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


3

No meu caso, a exclusão do atributo href resolve o problema, desde que haja uma função de clique atribuir a a.


3

Você impediu o comportamento padrão do navegador. Mas você não precisa criar uma diretiva para fazer isso.

É fácil como no exemplo a seguir:

my.component.html

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

my.component.ts

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

3

Atualizado para o 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

Eu tenho 4 soluções para tag de âncora fictícia.

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

4. Se você estiver usando o bootstrap:

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

0

Gostaria de saber por que ninguém está sugerindo routerLink e routerLinkActive (Angular 7)

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

Eu removi o href e agora estou usando isso. Ao usar o href, ele estava indo para o URL base ou recarregando a mesma rota novamente.


0

você precisa impedir o comportamento padrão do evento da seguinte maneira.

Em html

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

No arquivo ts

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

-1

Atualizado para o 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();
        }
    }
}

Usando

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

-1

A solução realmente simples é (click)="(null)"

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


talvez algum comentário por que esse technick é ruim?
Grigson

1
Escrever clique em qualquer lugar do código quando você não deseja um clique ruim
Jens Alenius

2
mas é exatamente isso que eu quero fazer: marque o local no código como "nada ao clicar", mas suporte a nova sintaxe. Construções como onclick = "javascript: void" são realmente feias. E href = "#" não é confiável, pois eles podem pular sua janela de exibição para o topo. Então eu não posso ver melhor alternativas
Grigson

Eu gosto da sua solução. Obrigado.
Mai Hữu Li

Veja minha nova resposta. Se você não quer o achor para navegar seu um botão 'tipo'
Jens Alenius
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.