Accéder à l'élément cliqué dans angularjs

173

Je suis relativement nouveau sur AngularJS et je soupçonne que je ne saisis pas un concept. J'utilise également Twitter Bootstrap et jQuery est chargé.

Flux de travail: l'utilisateur clique sur un lien dans une liste, la section «maître» est mise à jour et le lien utilisateur cliqué sur gagne la classe active.

Balisage HTML de base:

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

Faire cela dans jQuery:

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

Mais je ne peux pas comprendre comment intégrer Angular et jQuery pour y parvenir, car j'utilise Angular pour récupérer la liste principale (sous forme JSON) sur le serveur et mettre à jour une liste sur la page.

Comment intégrer cela? Je n'arrive pas à trouver l'élément sur lequel j'ai cliqué une fois que je suis dans la fonction de contrôleur angulaire

Manette:

function adminController($scope)
    {    
        $scope.setMaster = function(obj)
        {
            // How do I get clicked element's parent li?
            console.log(obj);
        }
    }
R Bas
la source

Réponses:

283

Alors qu'AngularJS vous permet de mettre la main sur un événement de clic (et donc une cible de celui-ci) avec la syntaxe suivante (notez l' $eventargument de la setMasterfonction; documentation ici: http://docs.angularjs.org/api/ng.directive : ngClick ):

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

ce n'est pas une manière très angulaire de résoudre ce problème. Avec AngularJS, l'accent est mis sur la manipulation du modèle. On muterait un modèle et laisser AngularJS déterminer le rendu.

La manière AngularJS de résoudre ce problème (sans utiliser jQuery et sans avoir besoin de passer l' $eventargument ) serait:

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

où les méthodes du contrôleur ressembleraient à ceci:

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

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

Voici le jsFiddle complet: http://jsfiddle.net/pkozlowski_opensource/WXJ3p/15/

pkozlowski.opensource
la source
198
FYI: $ event ne fonctionne que s'il est passé dans le balisage: ng-click="setMaster(section, $event)"juste un avertissement.
Ben Lesh
4
Pas vraiment, il doit être transmis à la fonction. En réalité, cependant, ce n'est probablement pas la meilleure idée de référencer des éléments spécifiques à dom comme celui-ci dans votre contrôleur. Généralement, quand $ event est utilisé, c'est dans le contexte de l'arrêt de la propagation ou autre: <a ng-click="doSomething(); $event.stopPropagation()">Click Just Me</a>
Ben Lesh
9
J'ai eu un problème en utilisant $ event.target car j'avais une icône à l'intérieur de mon bouton. Ainsi, parfois, le résultat cible est le bouton et parfois l'icône (selon l'endroit où j'ai cliqué). J'ai utilisé $ event.currentTarget au lieu de target et cela a fonctionné comme un charme.
lao
4
Bien que l'utilisation de $event.targetce type ne soit peut-être pas la «méthode angulaire», j'ai l'impression d'avoir une longue ng-repeatliste avec chaque élément nécessitant un auditeur pour évaluer un changement n'est pas efficace? Cliquer sur un élément signifierait que chaque élément de la liste entière doit être réévalué, n'est-ce pas? - pourquoi ne pas simplement cibler cet élément avec $event.targetpour basculer une classe CSS par exemple. Qu'est-ce que tu penses? Je travaille sur une application Phonegap et j'ai besoin de chaque ajustement de performance possible.
Bradley Flood
13
Je voudrais également recommander d'utiliser à la $event.currentTargetplace de $event.target. Si l'élément avec ng-click a des éléments enfants, si l'élément enfant est cliqué $event.targetdevient l'élément enfant. $event.currentTargetciblera toujours l'élément avec le ng-clic désigné.
Gene Parcellano