Zugriff auf geklicktes Element in anglejs

173

Ich bin relativ neu bei AngularJS und vermute, dass ich kein Konzept verstehe. Ich verwende auch Twitter Bootstrap und habe jQuery geladen.

Workflow: Der Benutzer klickt auf einen Link aus einer Liste, der Abschnitt "Master" wird aktualisiert und der Linkbenutzer, der auf "Aktiv" klickt, erhält eine aktive Klasse.

Grundlegendes HTML-Markup:

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

Tun Sie dies in jQuery:

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

Ich kann jedoch nicht herausfinden, wie Angular und jQuery integriert werden können, um dies zu erreichen, da ich Angular verwende, um die Hauptliste (in JSON-Form) vom Server abzurufen und eine Liste auf der Seite zu aktualisieren.

Wie integriere ich das? Ich kann das Element, auf das ich geklickt habe, nicht finden, wenn ich mich in der Winkelsteuerungsfunktion befinde

Regler:

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

Antworten:

283

Während AngularJS es Ihnen ermöglicht, ein Klickereignis (und damit ein Ziel davon) mit der folgenden Syntax in die Hand zu nehmen (beachten Sie das $eventArgument für die setMasterFunktion; Dokumentation hier: http://docs.angularjs.org/api/ng.directive) : ngClick ):

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

Dies ist kein sehr eckiger Weg, um dieses Problem zu lösen. Bei AngularJS liegt der Fokus auf der Modellmanipulation. Man würde ein Modell mutieren und AngularJS das Rendern herausfinden lassen.

Die AngularJS-Methode zur Lösung dieses Problems (ohne Verwendung von jQuery und ohne die Notwendigkeit, das $eventArgument zu übergeben ) wäre:

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

wo Methoden in der Steuerung so aussehen würden:

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

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

Hier ist die komplette jsFiddle: http://jsfiddle.net/pkozlowski_opensource/WXJ3p/15/

pkozlowski.opensource
quelle
198
Zu Ihrer Information: $ event funktioniert nur, wenn es im Markup übergeben wird: ng-click="setMaster(section, $event)"Nur ein Kopf hoch.
Ben Lesh
4
Nicht wirklich, es muss an die Funktion übergeben werden. In der Realität ist es jedoch wahrscheinlich nicht die beste Idee, dom-spezifische Dinge wie diese in Ihrem Controller zu referenzieren. Wenn $ event verwendet wird, geschieht dies im Allgemeinen im Zusammenhang mit dem Stoppen der Weitergabe oder dergleichen: <a ng-click="doSomething(); $event.stopPropagation()">Click Just Me</a>
Ben Lesh
9
Ich hatte ein Problem mit der Verwendung von $ event.target, da sich in meiner Schaltfläche ein Symbol befand. Manchmal ist das Zielergebnis die Schaltfläche und manchmal das Symbol (je nachdem, wo ich geklickt habe). Ich habe $ event.currentTarget anstelle von target verwendet und es hat wie ein Zauber funktioniert.
Lao
4
Obwohl die Verwendung $event.targetdieser Methode möglicherweise nicht der "eckige Weg" ist, ist es meiner Meinung ng-repeatnach nicht effizient , eine große Liste mit jedem Element zu haben, bei dem ein Listener zur Bewertung einer Änderung benötigt wird. Wenn Sie auf ein Element klicken, bedeutet dies, dass jedes Element in der gesamten Liste neu bewertet werden muss, oder? - Warum nicht einfach auf dieses eine Element abzielen, $event.targetum beispielsweise eine CSS-Klasse umzuschalten? Was denken Sie? Ich arbeite an einer Phonegap-App und muss jede Leistungsoptimierung, die ich kann, unter Druck setzen.
Bradley Flood
13
Ich würde auch empfehlen, $event.currentTargetanstelle von zu verwenden $event.target. Wenn das Element mit ng-click untergeordnete Elemente enthält, wird das untergeordnete Element zum untergeordneten Element, wenn auf das untergeordnete Element geklickt $event.targetwird. $event.currentTargetzielt immer mit dem angegebenen ng-Klick auf das Element ab.
Gene Parcellano