href sostituisce ng-click in Angular.js


118

Quando sono definiti entrambi gli attributi href e ng-click:

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

l' hrefattributo ha la precedenza su ng-click.

Sto cercando un modo per aumentare la priorità di ng-click.

href è richiesto per Twitter Bootstrap, non posso rimuoverlo.


Potresti approfondire "href è richiesto per Twitter Bootstrap"? Quale parte di esso? CSS o JavaScript?
pkozlowski.opensource

Il "widget" di navigazione di Twitter Bootstrap è configurato per utilizzare i collegamenti, se si aggiunge un pulsante ad esso, anche uno che ha lo stile per sembrare un collegamento, interrompe lo stile della navigazione. Probabilmente non è HTML semantico ma la soluzione di @ sketchfemme fa quello che io (e probabilmente Paul) voglio che faccia.
BenCr

Ignora tutto ciò che ho detto, la barra di navigazione funziona perfettamente con i pulsanti se usi l'HTML e le classi giuste. getbootstrap.com/components/#navbar
BenCr

Dovresti accettare la risposta di Mithu, che consiste nell'utilizzare un URL vuoto
Peter Morris

1
@Paul Il poster originale chiedeva come ottenere un <a href> per non navigare. La risposta accettata dice di passare a un pulsante. Anche se funziona non è la soluzione al problema, soprattutto se come me sei costretto a usare <a href> perché è un menu di bootstrap o qualcosa del genere. La soluzione corretta a questa domanda specifica è utilizzare un URL vuoto <a href="" ng-click="wwhat()"> Esci </a>: l'ho testato e posso confermare che funziona. Per fortuna qualcun altro ha fornito la risposta corretta o sarei ancora bloccato.
Peter Morris

Risposte:


35

Probabilmente dovresti usare solo un tag button se non hai bisogno di un uri.


Sì, se puoi approfondire come Twitter Bootstrap lo richiede, forse posso aiutarti di più.
Geoff

Come funziona con i motori di ricerca? Sto usando il routing AngularJS e ho bisogno di mantenere lo stato in un servizio, quindi per tutti i miei link di applicazioni interne utilizzo $ location, ma la rimozione di href rende impossibile ai motori di ricerca di seguire il sito.
Darrrrrren

2
i pulsanti non possono avere altri elementi al loro interno, quindi per lo styling, non vorresti farlo - se hai bisogno di cose al loro interno.
Sheriffderek

246

Questo esempio dal sito di documentazione angolare fa solo hrefsenza nemmeno assegnarlo a una stringa vuota:

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

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


3
Quando provo questo, tutti i link sembrano essere visitati, il che non è il comportamento che cerco. L'altro modo ( href="#") provoca un ricaricamento della pagina, anch'esso sbagliato.
Rhys van der Waerden

4
Questo fa sì che IE9 non mostri un cursore a mano. L'utilizzo lo href=""risolve.
Juampy NR

1
@juampy, la consegna del collegamento può essere gestita con CSS. Questa risposta data è il modo ufficiale di AngularJS per farlo.
thenetimp

Il # verrà trattato come un link hash.
Sheriffderek

3
<a href="javscript:void(0)" ng-click="logout()">Sign out</a>servirà bene anche te
Marios Fakiolas

88

Puoi semplicemente impedire il comportamento predefinito dell'evento clic direttamente nel tuo modello.

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

Per la documentazione angolare ,

Direttive come ngClick e ngFocus espongono un oggetto $ event nell'ambito di tale espressione.


11
Questa è un'ottima soluzione. Se si dispone di un href, è possibile fare clic con il pulsante destro del mouse per aprirlo in una nuova scheda, ma al clic sinistro viene chiamato ng-clic. Esattamente quello che stavo cercando
Tom Grant il

Ancora una volta un'ottima risposta. Sia il clic sinistro che quello destro funzionano
Jay Jay Jay

Ha funzionato alla grande per consentire i controlli del carousel Bootstrap senza attivare il routing. Grazie!
Jason Maggard

Perfetto! Posso continuare con i collegamenti e ottenere più indice in Google e utilizzare ng-click per chiamare in Ajax. Grazie.
Guilherme IA

Ottima soluzione, veloce e utile. Grazie!
Josue Rocha

72

Ecco un'altra soluzione:

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

cioè rimuovi semplicemente il # dall'attributo href


1
Per la domanda posta, questa dovrebbe essere la soluzione. Ha lavorato anche su Angular 1.1.5
Sindre

18
Sembra che <a href="" ng-click=""> impedirà il clic ng nel browser Android 2.3.x. Finalmente utilizzo <a href="javascript:void(0)" ng-click="">
duckegg

1
Il suggerimento di Duckegg è il migliore
Jiří Vypědřík

26

Solo un altro suggerimento. Se hai bisogno di un URL reale (per supportare l'accessibilità del browser) puoi fare quanto segue:

modello:

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

direttiva:

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

In questo modo il tuo codice in linkClicked () avrà la possibilità di essere eseguito prima di navigare al link


Questa soluzione funziona e cambia solo il comportamento del clic sinistro, il clic destro rimane intatto (menu contestuale), inclusa la possibilità di un collegamento in href. Quindi questa è una soluzione più generale rispetto a TooMuchTenacious, che in realtà risponde alla domanda in modo più diretto.
Exocom

21

In Angular, le <a>s sono direttive . In quanto tale, se hai un vuoto hrefo no href, Angular chiamerà event.preventDefault.

Dalla fonte :

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

Ecco un plnkr che mostra lo hrefscenario mancante .


13

Questo ha funzionato per me in IE 9 e AngularJS v1.0.7:

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

Grazie al commento di duckeggs per la soluzione funzionante!


Funziona, il link non cambia il tuo URL e non è contrassegnato come visitato. Migliore risposta!
Jim109

10

Ci sono così tante risposte a questa domanda qui, ma sembra che ci sia un po 'di confusione su ciò che sta realmente accadendo qui.

In primo luogo, la tua premessa

"href sostituisce ng-click in Angular.js"

è sbagliato. Quello che sta effettivamente accadendo è che dopo il tuo clic, l'evento di clic viene prima gestito da angular (definito dalla ng-clickdirettiva in angular 1.x e clickin angular 2.x +) e quindi continua a propagarsi (il che alla fine fa sì che il browser navighi al URL definito con l' hrefattributo) (vedere questo per ulteriori informazioni sulla propagazione degli eventi in javascript)

Se vuoi evitarlo, dovresti annullare la propagazione dell'evento utilizzando il metodo dell'interfaccia The EventpreventDefault() :

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

(Questa è pura funzionalità javascript e non ha nulla a che fare con angolare)

Ora, questo risolverà già il tuo problema ma questa non è la soluzione ottimale. Angular, giustamente, promuove il pattern MVC . Con questa soluzione, il tuo template html viene mischiato con la logica javascript. Dovresti cercare di evitarlo il più possibile e inserire la tua logica nel tuo controller angolare. Quindi sarebbe un modo migliore

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

E nel tuo metodo logout ():

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

Ora l'evento clic non raggiungerà il browser, quindi non tenterà di caricare il collegamento indicato da href. (Tuttavia, tieni presente che se l'utente fa clic con il pulsante destro del mouse sul collegamento e apre direttamente il collegamento, non ci sarà affatto un evento di clic. Invece caricherà direttamente l'URL indicato dall'attributo href.)

Per quanto riguarda i commenti sul colore dei collegamenti visitati nei browser. Anche in questo caso questo non ha nulla a che fare con angolare, se href="..."per impostazione predefinita punti a un URL visitato dal browser, il colore del collegamento sarà diverso. Questo è controllato da CSS: selezionato Selector , puoi modificare il tuo CSS per sovrascrivere questo comportamento:

a {
   color:pink;
}

PS1 :

Alcune risposte suggeriscono di utilizzare:

<a href .../>

hrefè una direttiva angolare. Quando il tuo modello viene elaborato da angular, questo verrà convertito in

<a href="" .../>

Questi due modi sono essenzialmente gli stessi.


5

Basta scrivere ng-click prima di href .. Ha funzionato per me

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

Non penso sia necessario rimuovere "#" da href. In seguito funziona con Angularjs 1.2.10

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

1

Puoi anche provare questo:

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

0

Aggiungo per te un esempio che funziona per me e puoi cambiarlo come vuoi.

Aggiungo il seguente codice all'interno del mio controller.

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

e per la mia pagina di visualizzazione aggiungo il codice qui sotto.

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

0

Hai provato a reindirizzare all'interno della funzione di logout stessa? Ad esempio, supponiamo che la tua funzione di logout sia la seguente

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

Allora puoi semplicemente avere

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

0

Per favore controlla questo

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.