href anula ng-click en Angular.js


118

Cuando se definen los atributos href y ng-click:

<a href="#" ng-click="logout()">Sign out</a>

el hrefatributo tiene prioridad sobre ng-click.

Estoy buscando una forma de aumentar la prioridad de ng-click.

href es necesario para Twitter Bootstrap, no puedo eliminarlo.


¿Podría dar más detalles sobre "href es necesario para Twitter Bootstrap"? ¿Qué parte de ella? CSS o JavaScript?
pkozlowski.opensource

El "widget" de navegación de Twitter Bootstrap está configurado para usar enlaces, si le agregas un botón, incluso uno que tenga un estilo que parezca un enlace, rompe el estilo de la navegación. Probablemente no sea HTML semántico, pero la solución de @ sketchfemme hace lo que yo (y probablemente Paul) queremos que haga.
BenCr

Ignore todo lo que dije, la barra de navegación funciona perfectamente con botones si usa el HTML y las clases correctos. getbootstrap.com/components/#navbar
BenCr

Debe aceptar la respuesta de Mithu, que es usar una URL vacía
Peter Morris

1
@Paul El cartel original preguntó cómo conseguir un <a href> para no navegar. La respuesta aceptada dice que cambie a un botón. Aunque eso funciona, no es la solución al problema, especialmente si, como yo, estás obligado a usar <a href> porque es un menú de arranque o algo así. La solución correcta a esta pregunta específica es usar una URL vacía <a href="" ng-click="whatever()"> Cerrar sesión </a>. Lo probé y puedo confirmar que funciona. Afortunadamente, alguien más proporcionó la respuesta correcta o todavía estaría atascado.
Peter Morris

Respuestas:


35

Probablemente debería usar una etiqueta de botón si no necesita un uri.


Sí, si puede explicar cómo lo requiere Twitter Bootstrap, tal vez pueda ayudar más.
Geoff

¿Cómo funciona esto con los motores de búsqueda? Estoy usando el enrutamiento AngularJS y necesito mantener el estado en un servicio, por lo que para todos los enlaces de mi aplicación interna uso $ location, pero al eliminar href, los motores de búsqueda no pueden seguir el sitio.
Darrrrrren

2
los botones no pueden tener otro elemento dentro de ellos, por lo que para el estilo, no querrá hacer eso, si necesita cosas dentro de ellos.
Sheriffderek

246

Este ejemplo del sitio de documentación angular simplemente lo hace hrefsin siquiera asignarlo a una cadena vacía:

[<a href ng-click="colors.splice($index, 1)">X</a>]

http://docs.angularjs.org/api/ng.directive:select


3
Cuando intento esto, parece que se visitan todos los enlaces, que no es el comportamiento que busco. La otra forma ( href="#") provoca una recarga de la página, que también es incorrecta.
Rhys van der Waerden

4
Esto hace que IE9 no muestre un cursor de mano. Usar lo href=""resuelve.
Juampy NR

1
@juampy, la entrega del enlace se puede manejar con CSS. Esta respuesta dada es la forma oficial de AngularJS de hacerlo.
thenetimp

El # será tratado como un enlace hash.
Sheriffderek

3
<a href="javscript:void(0)" ng-click="logout()">Sign out</a>también te servirá bien
Marios Fakiolas

88

Simplemente puede evitar el comportamiento predeterminado del evento de clic directamente en su plantilla.

<a href="#" ng-click="$event.preventDefault();logout()" />

Según la documentación angular ,

Directivas como ngClick y ngFocus exponen un objeto $ event dentro del alcance de esa expresión.


11
Esta es una gran solucion. Si tiene un href, puede hacer clic derecho para abrirlo en una nueva pestaña, pero al hacer clic con el botón izquierdo se llama ng-click. Exactamente lo que estaba buscando
Tom Grant

Una vez más una excelente respuesta. Tanto el clic izquierdo como el derecho funcionan
Jay Jay Jay

Funcionó muy bien para permitir controles de carrusel de Bootstrap sin activar el enrutamiento. ¡Gracias!
Jason Maggard

¡Perfecto! Puedo continuar con enlaces y obtener más índices en Google y usar ng-click para llamar a Ajax. Gracias.
Guilherme IA

Gran solución, rápida y útil. ¡Gracias!
Josue Rocha

72

Aquí hay otra solución:

<a href="" ng-click="logout()">Sign out</a>

es decir, simplemente elimine el # del atributo href


1
Para la pregunta formulada, esta debería ser la solución. Trabajó también en Angular 1.1.5
Sindre

18
Parece que <a href="" ng-click=""> impedirá el ng-click en el navegador Android 2.3.x. Finalmente uso <a href="javascript:void(0)" ng-click="">
duckegg

1
La sugerencia de Duckegg es la mejor
Jiří Vypědřík

26

Solo una pista más. Si necesita una URL real (para admitir la accesibilidad del navegador), puede hacer lo siguiente:

modelo:

<a ng-href="{{link}}" ng-click="$event.preventDefault(); linkClicked(link)">{{link}}</a>

directiva:

$scope.linkClicked = function(link){
    // your code here
    $location.path(link);
};

De esta manera, su código en linkClicked () tendrá la oportunidad de ejecutarse antes de navegar al enlace


Esta solución funciona y solo cambia el comportamiento del clic izquierdo, el clic derecho permanece intacto (menú contextual), incluida la posibilidad de un enlace en href. Así que esa es una solución más general en comparación con TooMuchTenacious, que en realidad responde a la pregunta de manera más directa.
Exocom

21

En Angular, <a>s son directivas . Como tal, si tiene un vacío hrefo no href, Angular llamaráevent.preventDefault .

De la fuente :

    element.on('click', function(event){
      // if we have no href url, then don't navigate anywhere.
      if (!element.attr(href)) {
        event.preventDefault();
      }
    });

Aquí hay un plnkr que demuestra el hrefescenario que falta .


13

Esto funcionó para mí en IE 9 y AngularJS v1.0.7:

<a href="javascript:void(0)" ng-click="logout()">Logout</a>

¡Gracias al comentario de duckeggs por la solución de trabajo!


Funciona, el enlace no cambia su URL y no está marcado como visitado. ¡La mejor respuesta!
Jim109

10

Hay tantas respuestas para esta pregunta aquí, pero parece que hay un poco de confusión sobre lo que realmente está sucediendo aquí.

Primero, tu premisa

"href anula ng-click en Angular.js"

Está Mal. Lo que realmente está sucediendo es que después de su clic, el evento de clic es manejado primero por angular (definido por la ng-clickdirectiva en angular 1.xy clicken angular 2.x +) y luego continúa propagándose (lo que eventualmente hace que el navegador navegue al URL definida con hrefatributo). (Consulte esto para obtener más información sobre la propagación de eventos en javascript).

Si desea evitar esto, debe cancelar la propagación del evento utilizando el método de la interfaz del eventopreventDefault() :

<a href="#" ng-click="$event.preventDefault();logout()" />

(Esta es una funcionalidad pura de JavaScript y no tiene nada que ver con angular)

Ahora, esto ya resolverá su problema, pero esta no es la solución óptima. Angular, legítimamente, promueve el patrón MVC . Con esta solución, su plantilla html se mezcla con la lógica javascript. Debería tratar de evitar esto tanto como sea posible y poner su lógica en su controlador angular. Entonces una mejor manera sería

<a href="#" ng-click="logout($event)" />

Y en su método logout ():

logout($event) {
   $event.preventDefault();
   ...
}

Ahora el evento de clic no llegará al navegador, por lo que no intentará cargar el enlace señalado href. (Sin embargo, tenga en cuenta que si el usuario hace clic con el botón derecho en el enlace y lo abre directamente, no habrá ningún evento de clic. En su lugar, cargará directamente la URL señalada por elhref atributo).

Respecto a los comentarios sobre el color del enlace visitado en los navegadores. Nuevamente, esto no tiene nada que ver con angular, si href="..."apunta a una URL visitada por su navegador de forma predeterminada, el color del enlace será diferente. Esto está controlado por CSS: Selector visitado , puede modificar su CSS para anular este comportamiento:

a {
   color:pink;
}

PS1 :

Algunas respuestas sugieren usar:

<a href .../>

hrefes una directiva angular. Cuando su plantilla es procesada por angular, esta se convertirá a

<a href="" .../>

Esas dos formas son esencialmente las mismas.


5

Simplemente escriba ng-click antes de href .. funcionó para mí

<!DOCTYPE html>
<html>

  <head>
    <script data-require="angular.js@1.5.0" data-semver="1.5.0" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
    <script>
    angular.module("module",[])
.controller("controller",function($scope){
  
  $scope.func =function(){
    console.log("d");
  }
  
})</script>
  </head>

  <body ng-app="module" ng-controller="controller">
    <h1>Hello ..</h1>
    <a ng-click="func()" href="someplace.html">Take me there</a>
  </body>

</html>


2

No creo que debas eliminar "#" de href. Siguiendo trabajos con Angularjs 1.2.10

<a href="#/" ng-click="logout()">Logout</a>

1

También puedes probar esto:

<div ng-init="myVar = 'www.thesoftdesign'">
        <h1>Tutorials</h1>
        <p>Go to <a ng-href="{{myVar}}">{{myVar}}</a> to learn!</p>
</div>

0

Agregaré para ti un ejemplo que me funciona y puedes cambiarlo como quieras.

Agrego el código de abajo dentro de mi controlador.

     $scope.showNumberFct = function(){
        alert("Work!!!!");
     }

y para mi página de vista agrego el siguiente código.

<a  href="" ng-model="showNumber" ng-click="showNumberFct()" ng-init="showNumber = false" >Click Me!!!</a>

0

¿Intentó redirigir dentro de la función de cierre de sesión? Por ejemplo, digamos que su función de cierre de sesión es la siguiente

$scope.logout = function()
{
  $scope.userSession = undefined;
  window.location = "http://www.yoursite.com/#"
}

Entonces puedes tener

<a ng-click="logout()">Sign out</a>

0

Por favor, chequee esto

<a href="#" ng-click="logout(event)">Logout</a>

 $scope.logout = function(event)


 {
event.preventDefault();
alert("working..");
}

0
//for dynamic elements - if you want it in ng-repeat do below code

angular.forEach($scope.data, function(value, key) {
     //add new value to object
    value.new_url  = "your url";
});

 <div ng-repeat="row in data"><a ng-href="{{ row.url_content }}"></a></div>

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.