Dostęp do klikniętego elementu w angularjs

173

Jestem stosunkowo nowy w AngularJS i podejrzewam, że nie rozumiem koncepcji. Używam również Twittera Bootstrap i mam załadowany jQuery.

Przepływ pracy: użytkownik klika łącze z listy, sekcja „główna” jest aktualizowana, a użytkownik klikający łącze uzyskuje aktywną klasę.

Podstawowe znaczniki HTML:

<ul class="list-holder" ng-controller="adminController">
   <li><a ng-click="setMaster('client')">Clients</li>
   <li><a ng-click="setMaster('employees')">Employees</li>
   <li><a ng-click="setMaster('etc')>Etc...</li>
</ul>

Robiąc to w jQuery:

jQuery(".list-holder").on('click', 'a', function(event){
    event.preventDefault();
jQuery(".list-holder li").removeClass('active');
jQuery(this).parent('li').addClass('active');
});

Ale nie mogę dowiedzieć się, jak zintegrować Angular i jQuery, aby to zrobić, ponieważ używam Angulara do pobierania listy głównej (w postaci JSON) z serwera i aktualizowania listy na stronie.

Jak to zintegrować? Nie mogę znaleźć elementu, na który kliknąłem, gdy jestem w funkcji kontrolera kątowego

Kontroler:

function adminController($scope)
    {    
        $scope.setMaster = function(obj)
        {
            // How do I get clicked element's parent li?
            console.log(obj);
        }
    }
R w dół
źródło

Odpowiedzi:

283

Podczas gdy AngularJS pozwala uzyskać rękę w zdarzeniu kliknięcia (a tym samym jego celu) z następującą składnią (zwróć uwagę na $eventargument setMasterfunkcji; dokumentacja tutaj: http://docs.angularjs.org/api/ng.directive : ngClick ):

function AdminController($scope) {    
  $scope.setMaster = function(obj, $event){
    console.log($event.target);
  }
}

nie jest to zbyt kanciasty sposób rozwiązania tego problemu. AngularJS skupia się na manipulacji modelem. Zmutowałoby się model i pozwoliłoby AngularJS znaleźć sposób renderowania.

Sposób rozwiązania tego problemu w AngularJS (bez użycia jQuery i bez konieczności przekazywania $eventargumentu ) byłby następujący:

<div ng-controller="AdminController">
    <ul class="list-holder">
        <li ng-repeat="section in sections" ng-class="{active : isSelected(section)}">
            <a ng-click="setMaster(section)">{{section.name}}</a>
        </li>
    </ul>
    <hr>
    {{selected | json}}
</div>

gdzie metody w kontrolerze wyglądałyby tak:

$scope.setMaster = function(section) {
    $scope.selected = section;
}

$scope.isSelected = function(section) {
    return $scope.selected === section;
}

Oto kompletny jsFiddle: http://jsfiddle.net/pkozlowski_opensource/WXJ3p/15/

pkozlowski.opensource
źródło
198
FYI: $ event nie działa, dopóki nie zostanie przekazany w znaczniku: ng-click="setMaster(section, $event)"tylko ostrzeżenie.
Ben Lesh
4
Niezupełnie, to musi zostać przekazane do funkcji. W rzeczywistości jednak prawdopodobnie nie jest najlepszym pomysłem odwoływanie się do rzeczy specyficznych dla domeny w kontrolerze. Generalnie, gdy używane jest zdarzenie $ event, ma to miejsce w kontekście zatrzymania propagacji itp .: <a ng-click="doSomething(); $event.stopPropagation()">Click Just Me</a>
Ben Lesh
9
Wystąpił problem z używaniem $ event.target, ponieważ w moim przycisku znajdowała się ikona. Dlatego czasami wynikiem docelowym jest przycisk, a czasami ikona (w zależności od tego, gdzie kliknąłem). Użyłem $ event.currentTarget zamiast celu i zadziałało to jak urok.
lao
4
Chociaż używanie w $event.targetten sposób może nie być „kanciastym sposobem”, czuję, że posiadanie dużej ng-repeatlisty z każdym elementem wymagającym słuchacza do oceny zmiany nie jest wydajne? Kliknięcie jednego elementu oznaczałoby, że każdy element na całej liście musiałby zostać ponownie oceniony, prawda? - dlaczego nie skupiać się tylko na tym jednym elemencie, $event.targetna przykład przełączając klasę CSS. Co myślisz? Pracuję nad aplikacją Phonegap i muszę wycisnąć wszystkie możliwe poprawki wydajności.
Bradley Flood
13
Chciałbym również polecić używanie $event.currentTargetzamiast $event.target. Jeśli element z ng-click ma elementy potomne, po kliknięciu $event.targetelementu potomnego staje się elementem podrzędnym. $event.currentTargetzawsze będzie kierować na element wyznaczonym ng-click.
Gene Parcellano