href remplace ng-click dans Angular.js


118

Lorsque les deux attributs href et ng-click sont définis:

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

l' hrefattribut est prioritaire sur ng-click.

Je recherche un moyen d'augmenter la priorité de ng-click.

href est requis pour Twitter Bootstrap, je ne peux pas le supprimer.


Pourriez-vous élaborer sur "href est requis pour Twitter Bootstrap"? Quelle partie de celui-ci? CSS ou JavaScript?
pkozlowski.opensource

Le "widget" de navigation de Twitter Bootstrap est configuré pour utiliser des liens, si vous y ajoutez un bouton, même celui qui est conçu pour ressembler à un lien, il brise le style de la navigation. Ce n'est probablement pas du HTML sémantique, mais la solution de @ sketchfemme fait ce que je (et probablement Paul) veut qu'elle fasse.
BenCr

Ignorez tout ce que j'ai dit, la barre de navigation fonctionne parfaitement avec les boutons si vous utilisez le bon HTML et les bonnes classes. getbootstrap.com/components/#navbar
BenCr

Vous devriez accepter la réponse de Mithu, qui consiste à utiliser une URL vide
Peter Morris

1
@Paul L'affiche originale a demandé comment obtenir un <a href> pour ne pas naviguer. La réponse acceptée dit de passer à un bouton. Bien que cela fonctionne, ce n'est pas la solution au problème, surtout si, comme moi, vous êtes obligé d'utiliser <a href> parce que c'est un menu bootstrap ou quelque chose comme ça. La bonne solution à cette question spécifique est d'utiliser une URL vide <a href="" ng-click="whatever()"> Déconnexion </a> - je l'ai testé et je peux confirmer que cela fonctionne. Heureusement, quelqu'un d'autre a fourni la bonne réponse ou je serais toujours bloqué.
Peter Morris

Réponses:


35

Vous devriez probablement simplement utiliser une balise de bouton si vous n'avez pas besoin d'un uri.


Oui, si vous pouvez expliquer comment Twitter Bootstrap l'exige, je peux peut-être vous aider davantage.
Geoff

Comment cela fonctionne-t-il avec les moteurs de recherche? J'utilise le routage AngularJS et je dois maintenir l'état d'un service, donc pour tous mes liens d'application internes, j'utilise $ location, mais la suppression de href empêche les moteurs de recherche de suivre le site.
Darrrrrren

2
les boutons ne peuvent pas avoir d'autre élément à l'intérieur, donc pour le style, vous ne voudriez pas faire cela - si vous avez besoin d'éléments à l'intérieur.
sheriffderek

246

Cet exemple du site de documentation angulaire se fait hrefsans même l'attribuer à une chaîne vide:

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

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


3
Lorsque j'essaie, tous les liens semblent être visités, ce qui n'est pas le comportement que je recherche. L'autre façon ( href="#") provoque un rechargement de page, ce qui est également faux.
Rhys van der Waerden

4
Cela empêche IE9 d'afficher un curseur de main. L'utilisation le href=""résout.
Juampy NR

1
@juampy, la main sur le lien peut être gérée avec CSS. Cette réponse donnée est la manière officielle AngularJS de le faire.
thenetimp

Le # sera traité comme un lien de hachage.
sheriffderek

3
<a href="javscript:void(0)" ng-click="logout()">Sign out</a>vous servira bien aussi
Marios Fakiolas

88

Vous pouvez simplement empêcher le comportement par défaut de l'événement de clic directement dans votre modèle.

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

Selon la documentation angulaire ,

Des directives telles que ngClick et ngFocus exposent un objet $ event dans la portée de cette expression.


11
C'est une excellente solution. Si vous avez un href, vous pouvez faire un clic droit pour l'ouvrir dans un nouvel onglet, mais sur un clic gauche, il appelle ng-clic. Exactement ce que je cherchais
Tom Grant

Encore une fois une excellente réponse. Les deux clics gauche et droit fonctionnent
Jay Jay Jay

Fonctionne très bien pour permettre les commandes de carrousel Bootstrap sans déclencher le routage. Merci!
Jason Maggard

Parfait! Je peux continuer avec des liens et obtenir plus d'index dans Google et utiliser ng-click pour appeler en Ajax. Merci.
Guilherme IA

Excellente solution, rapide et utile. Merci!
Josue Rocha

72

Voici une autre solution:

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

ie Supprimez simplement le # de l'attribut href


1
Pour la question posée, cela devrait être la solution. A également travaillé sur Angular 1.1.5
Sindre

18
Il semble que <a href="" ng-click=""> empêchera le ng-click dans le navigateur Android 2.3.x. J'utilise enfin <a href="javascript:void(0)" ng-click="">
duckegg

1
La suggestion de Duckegg est la meilleure
Jiří Vypědřík

26

Encore un indice. Si vous avez besoin d'une URL réelle (pour prendre en charge l'accessibilité du navigateur), vous pouvez effectuer les opérations suivantes:

modèle:

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

directif:

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

De cette façon, votre code dans linkClicked () aura la possibilité de s'exécuter avant de naviguer vers le lien


Cette solution fonctionne et ne modifie que le comportement du clic gauche, le clic droit reste intact (menu contextuel), y compris la possibilité d'un lien en href. C'est donc une solution plus générale par rapport à TooMuchTenacious, qui répond en fait plus directement à la question.
Exocom

21

Dans Angular, les <a>s sont des directives . En tant que tel, si vous avez un vide hrefou non href, Angular appellera event.preventDefault.

De la source :

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

Voici un plnkr démontrant le hrefscénario manquant .


13

Cela a fonctionné pour moi dans IE 9 et AngularJS v1.0.7:

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

Merci au commentaire de duckeggs pour la solution de travail!


Fonctionne, le lien ne change pas votre URL et n'est pas marqué comme visité. Meilleure réponse!
Jim109 du

10

Il y a tellement de réponses à cette question ici, mais il semble qu'il y ait un peu de confusion sur ce qui se passe réellement ici.

Premièrement, votre prémisse

"href remplace ng-click dans Angular.js"

est faux. Ce qui se passe réellement, c'est qu'après votre clic, l'événement de clic est d'abord géré par angular (défini par la ng-clickdirective en angular 1.x et clicken angular 2.x +), puis il continue à se propager (ce qui déclenche finalement le navigateur pour naviguer vers le url définie avec l' hrefattribut) (voir ceci pour en savoir plus sur la propagation d'événements en javascript)

Si vous souhaitez éviter cela, vous devez annuler la propagation de l'événement à l'aide de la méthode de l'interface The EventpreventDefault() :

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

(Ceci est une fonctionnalité javascript pure et n'a rien à voir avec angular)

Maintenant, cela résoudra déjà votre problème mais ce n'est pas la solution optimale. Angular, à juste titre, favorise le modèle MVC . Avec cette solution, votre modèle html est mélangé à la logique javascript. Vous devriez essayer d'éviter cela autant que possible et mettre votre logique dans votre contrôleur angulaire. Donc, une meilleure façon serait

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

Et dans votre méthode logout ():

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

Maintenant, l'événement de clic n'atteindra pas le navigateur, il n'essaiera donc pas de charger le lien pointé par href. (Cependant, notez que si l'utilisateur clique avec le bouton droit sur le lien et ouvre directement le lien, il n'y aura pas du tout d'événement de clic. Au lieu de cela, il chargera directement l'URL pointée par l' hrefattribut.)

Concernant les commentaires sur la couleur des liens visités dans les navigateurs. Encore une fois, cela n'a rien à voir avec angulaire, si href="..."votre navigateur pointe vers une URL visitée par défaut, la couleur du lien sera différente. Ceci est contrôlé par CSS: visité Selector , vous pouvez modifier votre css pour remplacer ce comportement:

a {
   color:pink;
}

PS1 :

Certaines réponses suggèrent d'utiliser:

<a href .../>

hrefest une directive angulaire. Lorsque votre modèle est traité par angulaire, il sera converti en

<a href="" .../>

Ces deux moyens sont essentiellement les mêmes.


5

Écrivez juste ng-click avant href .. cela a fonctionné pour moi

<!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

Je ne pense pas que vous deviez supprimer "#" de href. Travaux suivants avec Angularjs 1.2.10

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

1

Vous pouvez également essayer ceci:

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

0

Je vais ajouter pour vous un exemple qui fonctionne pour moi et vous pouvez le modifier à votre guise.

J'ajoute le code ci-dessous dans mon contrôleur.

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

et pour ma page d'affichage, j'ajoute le code ci-dessous.

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

0

Avez-vous essayé de rediriger à l'intérieur de la fonction de déconnexion elle-même? Par exemple, disons que votre fonction de déconnexion est la suivante

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

Alors tu peux juste avoir

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

0

S'il te plaît, vérifie cela

<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>

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.