Автоматически передавать $event с помощью ng-click?
Я знаю, что я могу получить доступ к событию click от ng-click
, если я передаю объект $event
следующим образом:
<button ng-click="myFunction($event)">Give me the $event</button>
function myFunction (event) {
typeof event !== "undefined" // true
}
Это немного раздражает необходимость пропускать $event
явным образом каждый раз. Можно ли установить ng-click
как-то передать его функции по умолчанию?
Ответы
Ответ 1
Взгляните на источник директивы ng-click
:
...
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});
});
});
};
}
Он показывает, как объект event
передается в выражение ng-click
, используя $event
как имя параметра. Это выполняется с помощью службы $parse, которая не позволяет параметрам истекать в целевую область, что означает ответ не, вы не можете получить доступ к объекту $event
любым другим но через параметр обратного вызова.
Ответ 2
Добавьте $event к ng-клику, например:
<button type="button" ng-click="saveOffer($event)" accesskey="S"></button>
Затем jQuery.Event был передан обратному вызову:
![enter image description here]()
Ответ 3
Как говорили другие, вы не можете строго делать то, о чем просите. Тем не менее, все инструменты, доступные для рамки angular, действительно доступны вам! Это означает, что вы можете написать свои собственные элементы и самостоятельно предоставить эту функцию. Я написал один из них в качестве примера, который вы можете увидеть на следующем plunkr (http://plnkr.co/edit/Qrz9zFjc7Ud6KQoNMEI1).
Ключевыми частями этого является то, что я определяю элемент "clickable" (не делайте этого, если вам нужна более старая поддержка IE). В коде, который выглядит так:
<clickable>
<h1>Hello World!</h1>
</clickable>
Затем я определил директиву, чтобы взять этот интерактивный элемент и превратить его в то, что я хочу (что-то, что автоматически устанавливает мое событие click):
app.directive('clickable', function() {
return {
transclude: true,
restrict: 'E',
template: '<div ng-transclude ng-click="handleClick($event)"></div>'
};
});
Наконец, в моем контроллере у меня есть событие клика, готовое к работе:
$scope.handleClick = function($event) {
var i = 0;
};
Теперь стоит отметить, что это жестко кодирует имя метода, который обрабатывает событие click. Если вы хотите устранить это, вы должны предоставить директиву имя вашего обработчика кликов и "tada" - у вас есть элемент (или атрибут), который вы можете использовать, и никогда не должны вводить "$ event" снова.
Надеюсь, что это поможет!
Ответ 4
Я бы не рекомендовал это делать, но вы можете переопределить директиву ngClick
, чтобы делать то, что вы ищете. Это не значит, что нужно.
С учетом первоначальной реализации:
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});
});
});
};
}
Мы можем сделать это, чтобы переопределить его:
// 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;
});
});
Затем вы передадите свои функции следующим образом:
<div ng-click="func"></div>
в отличие от:
<div ng-click="func()"></div>
jsBin: http://jsbin.com/piwafeke/3/edit
Как я уже сказал, я бы рекомендовал не, но это доказательство концепции, показывающее вам, что да - вы действительно можете перезаписать/расширить/увеличить встроенное поведение angular, чтобы оно соответствовало вашим необходимо. Без необходимости копать все это в оригинальной реализации.
Пожалуйста, используйте его с осторожностью, если вы решите пойти по этому пути (это очень весело).