如何创建具有类似ng events的$ event的自定义事件指令

时间:2018-10-16 15:48:32

标签: javascript angularjs

我有这样的AngularJS指令:

(function () {
    'use strict';
    // better click that ingore drag
    angular
        .module('module')
        .directive('exClick', exClick);

    exClick.$inject = [];
    function exClick() {
        return {
            restrict: 'A',
            scope: {
              exClick: '&'
            },
            link: function ($scope, $element) {
                var isDragging = false;
                function mousemove() {
                    isDragging = true;
                    $(window).off('mousemove', mousemove);
                }
                var timer;
                $element.mousedown(function() {
                    isDragging = false;
                    // there is wierd issue where move is triggerd just
                    // after mousedown even without moving the cursor
                    timer = setTimeout(function() {
                        $(window).mousemove(mousemove);
                    }, 100);
                }).mouseup(function(e) {
                    var wasDragging = isDragging;
                    isDragging = false;
                    clearTimeout(timer);
                    $(window).off('mousemove', mousemove);
                    if (!wasDragging) {
                        $scope.$apply($scope.exClick);
                    }
                });

                $scope.$on('$destroy', function() {
                    $(window).off('mousemove', mousemove);
                    $element.off('mousedown mouseup');
                });
            }
        }
    }
})();

,并且我想像正常ng事件一样使用ng单击表行,并在行控件上单击ng-click="$event.stopPropagation()"。我已将行替换为ex-click,并希望使用ex-click="$event.stopPropagation()"。我可以使用ng-mouseup阻止该事件的发生,但是我想知道如何使自定义事件的行为与本机ng事件相同。

我尝试过:

$scope.exClick({$event: e});

$scope.$event = e;
$scope.$apply();
$scope.exClick();

1 个答案:

答案 0 :(得分:0)

source code ngClick中找到的是一种普通的AngularJS指令(添加的方式有所不同,但是它具有相同的编译和链接,因此应该工作相同)。

下面是代码的副本供参考:

forEach(
  'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste'.split(' '),
  function(eventName) {
    var directiveName = directiveNormalize('ng-' + eventName);
    ngEventDirectives[directiveName] = ['$parse', '$rootScope', '$exceptionHandler', function($parse, $rootScope, $exceptionHandler) {
      return createEventDirective($parse, $rootScope, $exceptionHandler, directiveName, eventName, forceAsyncEvents[eventName]);
    }];
  }
);

function createEventDirective($parse, $rootScope, $exceptionHandler, directiveName, eventName, forceAsync) {
  return {
    restrict: 'A',
    compile: function($element, attr) {
      // NOTE:
      // We expose the powerful `$event` object on the scope that provides access to the Window,
      // etc. This is OK, because expressions are not sandboxed any more (and the expression
      // sandbox was never meant to be a security feature anyway).
      var fn = $parse(attr[directiveName]);
      return function ngEventHandler(scope, element) {
        element.on(eventName, function(event) {
          var callback = function() {
            fn(scope, {$event: event});
          };

          if (!$rootScope.$$phase) {
            scope.$apply(callback);
          } else if (forceAsync) {
            scope.$evalAsync(callback);
          } else {
            try {
              callback();
            } catch (error) {
              $exceptionHandler(error);
            }
          }
        });
      };
    }
  };
}