Подтвердить что ты не робот

Автоматически передавать $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 как-то передать его функции по умолчанию?

4b9b3361

Ответ 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, чтобы оно соответствовало вашим необходимо. Без необходимости копать все это в оригинальной реализации.

Пожалуйста, используйте его с осторожностью, если вы решите пойти по этому пути (это очень весело).