Доступ до натиснутого елемента в 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);
        }
    }

Відповіді:


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/


198
FYI: $ подія не працює, якщо це не ng-click="setMaster(section, $event)"зроблено в розмітці: Лише вгору.
Бен Леш

4
Насправді це потрібно передати у функцію. Насправді, однак, це, мабуть, не найкраща ідея посилатись на специфічні для дому речі у цьому контролері. Зазвичай, коли використовується $ подія, це відбувається в контексті припинення розповсюдження тощо: <a ng-click="doSomething(); $event.stopPropagation()">Click Just Me</a>
Бен Леш

9
У мене виникла проблема із використанням $ event.target, оскільки у мене в межах кнопки був значок. Отже, іноді цільовим результатом є кнопка, а іноді - значок (залежно від того, де я натиснув). Я використовував $ event.currentTarget замість цілі, і він працював як шарм.
лао

4
Хоча $event.targetподібне використання може бути не «кутовим способом», я відчуваю, що великий ng-repeatсписок з кожним елементом, який потребує слухача, щоб оцінити зміни, не є ефективним? Натиснувши на один елемент, означає, що кожен елемент у списку повинен бути переоцінений, чи не так? - чому б не просто націлити цей елемент на, наприклад, $event.targetдля перемикання класу CSS. Що ти думаєш? Я працюю над додатком Phonegap і мені потрібно видавити всі налаштування продуктивності, які я можу.
Бредлі Флуд

13
Я також хотів би рекомендувати використовувати $event.currentTargetзамість цього $event.target. Якщо в елементі ng-click є дочірні елементи, якщо дочірній елемент клацається, $event.targetстає дочірнім елементом. $event.currentTargetзавжди буде орієнтуватися на елемент позначеним натисканням ng.
Джин Парчеллано
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.