href zastępuje ng-click w Angular.js


118

Gdy zdefiniowane są oba atrybuty href i ng-click:

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

hrefatrybut ma pierwszeństwo przed NG-click.

Szukam sposobu na podniesienie priorytetu ng-click.

href jest wymagany dla Twitter Bootstrap, nie mogę go usunąć.


Czy mógłbyś rozwinąć temat „href jest wymagany dla Twitter Bootstrap”? Która część tego? CSS czy JavaScript?
pkozlowski.opensource

"Widżet" nawigacyjny Twitter Bootstrap jest skonfigurowany do używania linków, jeśli dodasz do niego przycisk, nawet taki, który wygląda jak link, zepsuje styl nawigacji. Prawdopodobnie nie jest to semantyczny HTML, ale rozwiązanie @ sketchfemme robi to, co ja (i prawdopodobnie Paul) chcę.
BenCr,

Zignoruj ​​wszystko, co powiedziałem, pasek nawigacyjny działa doskonale z przyciskami, jeśli używasz odpowiedniego kodu HTML i klas. getbootstrap.com/components/#navbar
BenCr,

Powinieneś zaakceptować odpowiedź Mithu, która polega na użyciu pustego adresu URL
Peter Morris

1
@Paul Oryginalny plakat pytał, jak uzyskać <a href>, aby nie nawigować. Zaakceptowana odpowiedź mówi, aby przełączyć się na przycisk. Chociaż to działa, nie jest to rozwiązanie problemu, zwłaszcza jeśli tak jak ja jesteś zmuszony użyć <a href>, ponieważ jest to menu startowe lub coś w tym rodzaju. Prawidłowym rozwiązaniem tego konkretnego pytania jest użycie pustego adresu URL <a href="" ng-click="whthing()"> Wyloguj się </a> - przetestowałem to i mogę potwierdzić, że działa. Na szczęście ktoś inny udzielił poprawnej odpowiedzi, inaczej nadal bym utknął.
Peter Morris

Odpowiedzi:


35

Prawdopodobnie powinieneś po prostu użyć tagu przycisku, jeśli nie potrzebujesz URI.


Tak, jeśli możesz wyjaśnić, jak wymaga tego Twitter Bootstrap, może mógłbym pomóc więcej.
Geoff

Jak to działa w przypadku wyszukiwarek? Używam routingu AngularJS i muszę utrzymywać stan w usłudze, więc dla wszystkich moich wewnętrznych linków aplikacji używam $ location, ale usunięcie atrybutu href uniemożliwia wyszukiwarkom śledzenie całej witryny.
Darrrrrren

2
przyciski nie mogą mieć w sobie innego elementu, więc do stylizacji nie chciałbyś tego robić - jeśli potrzebujesz rzeczy w środku.
szeryfderek

246

Ten przykład z kątowej witryny dokumentacji po prostu działa hrefbez przypisywania go do pustego ciągu:

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

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


3
Kiedy próbuję, wszystkie linki wydają się być odwiedzane, co nie jest zachowaniem, którego szukam. W drugą stronę ( href="#") powoduje przeładowanie strony, co również jest błędne.
Rhys van der Waerden

4
To sprawia, że ​​IE9 nie pokazuje kursora rączki. Używanie href=""go rozwiązuje.
Juampy NR

1
@juampy, przekazanie linku może być obsługiwane przez CSS. Ta udzielona odpowiedź jest oficjalnym sposobem AngularJS, aby to zrobić.
thenetimp

# Będzie traktowany jak link z krzyżykiem.
szeryfderek

3
<a href="javscript:void(0)" ng-click="logout()">Sign out</a>będzie ci również służyć
Marios Fakiolas

88

Możesz po prostu zapobiec domyślnemu zachowaniu zdarzenia kliknięcia bezpośrednio w szablonie.

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

Zgodnie z dokumentacją kątową ,

Dyrektywy takie jak ngClick i ngFocus ujawniają obiekt $ event w zakresie tego wyrażenia.


11
To świetne rozwiązanie. Jeśli masz href, możesz kliknąć prawym przyciskiem myszy, aby otworzyć go w nowej karcie, ale po kliknięciu lewym przyciskiem wywołuje ng-click. Dokładnie to, czego szukałem
Tom Grant

Jeszcze raz świetna odpowiedź. Kliknięcie lewym i prawym przyciskiem działa
Jay Jay Jay

Działał świetnie, umożliwiając sterowanie karuzelą Bootstrap bez wyzwalania routingu. Dzięki!
Jason Maggard

Idealny! Mogę kontynuować z linkami i uzyskać więcej indeksu w Google i używać ng-click, aby dzwonić w Ajax. Dzięki.
Guilherme IA

Świetne rozwiązanie, szybkie i przydatne. Dzięki!
Josue Rocha

72

Oto inne rozwiązanie:

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

tzn. Po prostu usuń # z atrybutu href


1
Na zadane pytanie powinno to być rozwiązanie. Pracowałem również nad Angular 1.1.5
Sindre,

18
Wygląda na to, że <a href="" ng-click=""> uniemożliwi ng-click w przeglądarce Android 2.3.x. W końcu używam <a href="javascript:void(0)" ng-click="">
duckegg

1
Sugestia Duckegga jest najlepsza
Jiří Vypědřík

26

Jeszcze tylko jedna wskazówka. Jeśli potrzebujesz prawdziwego adresu URL (do obsługi dostępności przeglądarki), możesz wykonać następujące czynności:

szablon:

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

dyrektywa:

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

W ten sposób twój kod w linkClicked () będzie miał szansę na wykonanie przed przejściem do linku


To rozwiązanie działa i zmienia tylko zachowanie kliknięcia lewym przyciskiem myszy, kliknięcie prawym przyciskiem pozostaje nienaruszone (menu kontekstowe), w tym możliwość utworzenia łącza w href. Jest to więc bardziej ogólne rozwiązanie w porównaniu z TooMuchTenacious, które w rzeczywistości odpowiada na pytanie bardziej bezpośrednio.
Exocom

21

W Angular <a>s są dyrektywami . W związku z tym, jeśli masz pusty hreflub nie href, Angular zadzwoni event.preventDefault.

Ze źródła :

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

Oto plnkr demonstrujący brakujący hrefscenariusz.


13

To działało dla mnie w IE 9 i AngularJS v1.0.7:

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

Dzięki komentarzowi duckeggs za działające rozwiązanie!


Działa, link nie zmienia adresu URL i nie jest oznaczony jako odwiedzony. Najlepsza odpowiedź!
Jim109

10

Jest tak wiele odpowiedzi na to pytanie, ale wydaje się, że jest trochę nieporozumień co do tego, co się tutaj właściwie dzieje.

Po pierwsze, twoje założenie

„href zastępuje ng-click w Angular.js”

jest źle. W rzeczywistości po kliknięciu zdarzenie kliknięcia jest najpierw obsługiwane przez angular (zdefiniowane przez ng-clickdyrektywę w angular 1.x i clickangular 2.x +), a następnie kontynuuje propagację (co ostatecznie powoduje przejście przeglądarki do url zdefiniowany z hrefatrybutem). (Zobacz to, aby uzyskać więcej informacji na temat propagacji zdarzeń w javascript)

Jeśli chcesz tego uniknąć, powinieneś anulować propagację zdarzenia za pomocą metody interfejsu The EventpreventDefault() :

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

(To jest czysta funkcjonalność javascript i nie ma nic wspólnego z angularem)

Teraz to już rozwiąże twój problem, ale nie jest to optymalne rozwiązanie. Angular słusznie promuje wzorzec MVC . Dzięki temu rozwiązaniu Twój szablon HTML jest mieszany z logiką javascript. Powinieneś starać się tego unikać tak bardzo, jak to możliwe i umieścić swoją logikę w kontrolerze kątowym. Więc lepszy sposób byłby

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

A w metodzie logout ():

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

Teraz zdarzenie click nie dotrze do przeglądarki, więc nie spróbuje załadować wskazanego linku href. (Należy jednak pamiętać, że jeśli użytkownik kliknie link prawym przyciskiem myszy i bezpośrednio go otworzy, nie będzie w ogóle zdarzenia kliknięcia. Zamiast tego zostanie bezpośrednio załadowany adres URL wskazany przez hrefatrybut).

Odnośnie komentarzy na temat koloru odwiedzanych linków w przeglądarkach. Ponownie nie ma to nic wspólnego z angularem, jeśli href="..."domyślnie kierujesz na odwiedzany adres URL przez przeglądarkę, kolor linku będzie inny. Jest to kontrolowane przez CSS: odwiedził Selector , możesz zmodyfikować swój css, aby nadpisać to zachowanie:

a {
   color:pink;
}

PS1 :

Niektóre odpowiedzi sugerują użycie:

<a href .../>

hrefjest dyrektywą kątową. Gdy szablon jest przetwarzany przez kątowe, zostanie on przekonwertowany na

<a href="" .../>

Te dwa sposoby są zasadniczo takie same.


5

Po prostu napisz ng-click przed href .. Zadziałało dla mnie

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

Myślę, że nie musisz usuwać znaku „#” z href. Następujące prace z Angularjs 1.2.10

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

1

Możesz także spróbować tego:

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

0

Dodam dla Ciebie przykład, który działa dla mnie i możesz go zmienić, jak chcesz.

Dodaję poniższy kod w moim kontrolerze.

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

a na mojej stronie widoku dodaję poniższy kod.

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

0

Czy próbowałeś przekierować wewnątrz samej funkcji wylogowania? Załóżmy na przykład, że funkcja wylogowania jest następująca

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

Wtedy możesz po prostu mieć

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

0

Proszę to sprawdzić

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.