Ich weiß, dass ich Zugriff auf das Klickereignis erhalten kann, ng-click
wenn ich das $event
Objekt wie folgt übergebe:
<button ng-click="myFunction($event)">Give me the $event</button>
<script>
function myFunction (event) {
typeof event !== "undefined" // true
}
</script>
Es ist ein bisschen ärgerlich, $event
jedes Mal explizit passieren zu müssen . Ist es möglich, es so einzustellen ng-click
, dass es standardmäßig an die Funktion übergeben wird?
undefined
sollte"undefined"
, sonst wird der Ausdruck immer als falsch ausgewertet, da ertypeof
eine Zeichenfolge zurückgibt.$event
sowieso brauchen .myFunction
ist Teil eines Controllers. Ein Controller sollte sich nicht um die Benutzeroberfläche kümmern. Darüber hinaus hat eine einfache Schaltfläche keine Standardaktion. Und Winkel verhindert sowieso viele Standardaktionen. Während Sie Recht haben, ist es natürlich schwer, sich einen guten Anwendungsfall vorzustellen.contextMenu
die verschiedene Funktionen für den Bereich (Öffnen, Schließen, Umschalten) bereitstellt, die mit dem Namen eines bestimmten aufgerufen werdencontextMenu
, zng-click="account_menu.toggle()"
. Das Menü selbst befindet sich in einem anderen Element, z<div context-menu="account_menu"></div>"
. Um das Menü auf der Seite direkt unter dem aufgerufenen Triggerelement korrekt zu positionierentoggle()
, möchte ich aufng-click
das$event.target
Element zugreifen , damit ich seine Koordinaten abrufen kann. Lassen Sie mich wissen, ob es einen einfacheren Weg gibt :)Antworten:
Werfen Sie einen Blick auf die
ng-click
Quelle der Richtlinie:... compile: function($element, attr) { var fn = $parse(attr[directiveName]); return function(scope, element, attr) { element.on(lowercase(name), function(event) { scope.$apply(function() { fn(scope, {$event:event}); }); }); }; }
Es zeigt , wie das
event
Objekt wird weitergegeben an denng-click
Ausdruck, indem$event
als Name des Parameters. Dies erfolgt durch den $ parse-Dienst, der nicht zulässt, dass die Parameter in den Zielbereich übergehen. Dies bedeutet, dass die Antwort Nein lautet . Sie können$event
nur über den Rückrufparameter auf das Objekt zugreifen .quelle
Fügen Sie ein
$event
zu demng-click
, zum Beispiel:<button type="button" ng-click="saveOffer($event)" accesskey="S"></button>
Dann
jQuery.Event
wurde das an den Rückruf übergeben:quelle
Wie andere sagten, können Sie nicht genau das tun, wonach Sie fragen. Das heißt, alle Werkzeuge, die für das Winkelgerüst verfügbar sind, stehen Ihnen tatsächlich auch zur Verfügung! Das bedeutet, dass Sie Ihre eigenen Elemente schreiben und diese Funktion selbst bereitstellen können. Ich habe eines davon als Beispiel geschrieben, das Sie im folgenden Abschnitt sehen können ( http://plnkr.co/edit/Qrz9zFjc7Ud6KQoNMEI1 ).
Die wichtigsten Teile davon sind, dass ich ein "anklickbares" Element definiere (tun Sie dies nicht, wenn Sie ältere IE-Unterstützung benötigen). In Code, der aussieht wie:
<clickable> <h1>Hello World!</h1> </clickable>
Dann habe ich eine Anweisung definiert, um dieses anklickbare Element in das zu verwandeln, was ich möchte (etwas, das mein Klickereignis automatisch einrichtet):
app.directive('clickable', function() { return { transclude: true, restrict: 'E', template: '<div ng-transclude ng-click="handleClick($event)"></div>' }; });
Endlich in meinem Controller habe ich das Klickereignis bereit zu gehen:
$scope.handleClick = function($event) { var i = 0; };
Nun ist anzumerken, dass dies den Namen der Methode codiert, die das Klickereignis behandelt. Wenn Sie dies beseitigen möchten, sollten Sie in der Lage sein, der Direktive den Namen Ihres Klick-Handlers und "tada" zu geben - Sie haben ein Element (oder Attribut), das Sie verwenden können, und müssen "$ event" nie wieder einfügen.
Hoffentlich hilft das!
quelle
Ich würde dies nicht empfehlen, aber Sie können die
ngClick
Anweisung überschreiben, um das zu tun, wonach Sie suchen. Das heißt nicht, du solltest.Mit Blick auf die ursprüngliche Implementierung:
compile: function($element, attr) { var fn = $parse(attr[directiveName]); return function(scope, element, attr) { element.on(lowercase(name), function(event) { scope.$apply(function() { fn(scope, {$event:event}); }); }); }; }
Wir können dies tun, um es zu überschreiben:
// Go into your config block and inject $provide. app.config(function ($provide) { // Decorate the ngClick directive. $provide.decorator('ngClickDirective', function ($delegate) { // Grab the actual directive from the returned $delegate array. var directive = $delegate[0]; // Stow away the original compile function of the ngClick directive. var origCompile = directive.compile; // Overwrite the original compile function. directive.compile = function (el, attrs) { // Apply the original compile function. origCompile.apply(this, arguments); // Return a new link function with our custom behaviour. return function (scope, el, attrs) { // Get the name of the passed in function. var fn = attrs.ngClick; el.on('click', function (event) { scope.$apply(function () { // If no property on scope matches the passed in fn, return. if (!scope[fn]) { return; } // Throw an error if we misused the new ngClick directive. if (typeof scope[fn] !== 'function') { throw new Error('Property ' + fn + ' is not a function on ' + scope); } // Call the passed in function with the event. scope[fn].call(null, event); }); }); }; }; return $delegate; }); });
Dann würden Sie Ihre Funktionen wie folgt übergeben:
<div ng-click="func"></div>
im Gegensatz zu:
<div ng-click="func()"></div>
jsBin : http://jsbin.com/piwafeke/3/edit
Wie gesagt, ich würde dies nicht empfehlen, aber es ist ein Proof of Concept, der Ihnen zeigt, dass Sie das eingebaute Winkelverhalten tatsächlich überschreiben / erweitern / erweitern können, um es Ihren Anforderungen anzupassen. Ohne all das tief in die ursprüngliche Implementierung eintauchen zu müssen.
Gehen Sie bitte vorsichtig damit um, wenn Sie sich für diesen Weg entscheiden (es macht jedoch viel Spaß).
quelle