代码之家  ›  专栏  ›  技术社区  ›  jcubic

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

  •  1
  • jcubic  · 技术社区  · 7 年前

    我有这样的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-click="$event.stopPropagation()" . 我已经用ex click替换了行,我想使用 ex-click="$event.stopPropagation()" . 我可以使用ng mouseup来防止事件发生,但是我想知道如何使我的自定义事件与本机ng事件的行为相同。

    我试过:

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

    $scope.$event = e;
    $scope.$apply();
    $scope.exClick();
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   jcubic    7 年前

    发现于 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);
                }
              }
            });
          };
        }
      };
    }