Доступ к нажатому элементу в angularjs

173

Я относительно новичок в AngularJS и подозреваю, что не понимаю концепцию. Я также использую Twitter Bootstrap и загрузил jQuery.

Рабочий процесс: пользователь щелкает ссылку из списка, обновляется раздел «мастер», и пользователь нажимает на ссылку, чтобы получить активный класс.

Основная 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>

Делаем это в jQuery:

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

Но я не могу понять, как интегрировать Angular и jQuery, чтобы добиться этого, потому что я использую Angular, чтобы получить основной список (в форме JSON) с сервера и обновить список на странице.

Как мне это интегрировать? Кажется, я не могу найти элемент, на который нажал, когда нахожусь в функции углового контроллера

контроллер:

function adminController($scope)
    {    
        $scope.setMaster = function(obj)
        {
            // How do I get clicked element's parent li?
            console.log(obj);
        }
    }
R Down
источник

Ответы:

283

В то время как AngularJS позволяет вам получить руку на событие щелчка (и, следовательно, его цель) со следующим синтаксисом (обратите внимание на $eventаргумент setMasterфункции; документация здесь: http://docs.angularjs.org/api/ng.directive : ngClick ):

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

это не очень угловой способ решения этой проблемы. В AngularJS основное внимание уделяется манипулированию моделью. Можно было бы изменить модель и позволить AngularJS вычислить рендеринг.

AngularJS-способ решения этой проблемы (без использования jQuery и без необходимости передавать $eventаргумент ) будет:

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

где методы в контроллере будут выглядеть так:

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

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

Вот полный jsFiddle: http://jsfiddle.net/pkozlowski_opensource/WXJ3p/15/

pkozlowski.opensource
источник
198
К вашему сведению: событие $ не работает, если оно не передано в разметке: ng-click="setMaster(section, $event)"просто один на один.
Бен Леш
4
Не совсем, это нужно передать функции. В действительности, тем не менее, вероятно, не самая лучшая идея ссылаться на подобные вещи в вашем контроллере. Обычно, когда используется $ event, это происходит в контексте остановки распространения или тому подобного: <a ng-click="doSomething(); $event.stopPropagation()">Click Just Me</a>
Бен Леш,
9
У меня была проблема с использованием $ event.target, потому что внутри моей кнопки был значок. Поэтому иногда целевым результатом является кнопка, а иногда значок (в зависимости от того, где я щелкнул). Я использовал $ event.currentTarget вместо target, и это работало как шарм.
Лаос
4
Хотя $event.targetтакое использование не может быть «угловым путем», я чувствую, что иметь большой ng-repeatсписок с каждым элементом, нуждающимся в слушателе для оценки изменений, неэффективно? Нажатие на один элемент будет означать, что каждый элемент во всем списке должен быть переоценен правильно? почему бы просто не нацелить этот элемент с помощью $event.targetпереключения класса CSS, например. Что вы думаете? Я работаю над приложением PhoneGap, и мне нужно выжать все возможные улучшения.
Брэдли Флад
13
Я также хотел бы рекомендовать использовать $event.currentTargetвместо $event.target. Если элемент с ng-click имеет дочерние элементы, если дочерний элемент нажат, $event.targetстановится дочерним элементом. $event.currentTargetбудет всегда предназначаться для элемента с назначенным ng-щелчком.
Джин Парчелано