【问题标题】:How to stop $broadcast events in AngularJS?如何在 AngularJS 中停止 $broadcast 事件?
【发布时间】:2013-03-14 21:43:32
【问题描述】:

是否有一种内置方法可以阻止 $broadcast 事件沿作用域链向下移动?

$broadcast 事件传递的事件对象没有stopPropagation 方法(如docs on $rootScope 提到的那样。)但是this merged pull request 建议$broadcast 事件可以调用stopPropagation

【问题讨论】:

    标签: angularjs angularjs-scope


    【解决方案1】:

    来自 angularJS 1.1.2 源代码的片段:

    $emit: function(name, args) {
        // ....
        event = {
            name: name,
            targetScope: scope,
            stopPropagation: function() {
                stopPropagation = true;
            },
            preventDefault: function() {
                event.defaultPrevented = true;
            },
            defaultPrevented: false
        },
        // ....
    }
    
    $broadcast: function(name, args) {
        // ...
        event = {
            name: name,
            targetScope: target,
            preventDefault: function() {
                event.defaultPrevented = true;
            },
            defaultPrevented: false
        },
        // ...
    }
    

    如您所见,$broadcast 中的事件对象没有“stopPropagation”。

    您可以使用 preventDefault 代替 stopPropagation 来将事件标记为“不需要处理此事件”。这不会停止事件传播,但这会告诉子范围:“不需要处理此事件”

    示例:http://jsfiddle.net/C8EqT/1/

    【讨论】:

    • 使用defaultPrevented 作为标志来表示被忽略的事件是有意义的。
    • 这个例子的真正关键是这些行:'“不需要处理这个事件”:- 这不会停止事件传播,但这会告诉子范围:“不需要处理这个事件”'作为 preventDefault 的默认行为“preventDefault() 方法不会阻止事件通过 DOM 进一步传播。使用 stopPropagation() 方法来处理这个” stopPropagation:事件将在事件之前完成对当前 EventTarget 上的所有侦听器的调度流动停止。
    【解决方案2】:

    由于广播没有 stopPropagation 方法,您需要使用 defaultPrevented 属性,这在递归指令中是有意义的。

    在这里看看这个 plunker:Plunkr

    $scope.$on('test', function(event) { if (!event.defaultPrevented) { event.defaultPrevented = true; console.log('Handle event here for the root node only.'); } });

    【讨论】:

      【解决方案3】:

      为此我实现了一个事件窃贼:

      .factory("stealEvent", [function () {
      
        /**
         * If event is already "default prevented", noop.
         * If event isn't "default prevented", executes callback.
         * If callback returns a truthy value or undefined,
         * stops event propagation if possible, and flags event as "default prevented".
         */
        return function (callback) {
          return function (event) {
            if (!event.defaultPrevented) {
              var stopEvent = callback.apply(null, arguments);
              if (typeof stopEvent === "undefined" || stopEvent) {
                event.stopPropagation && event.stopPropagation();
                event.preventDefault();
              }
            }
          };
        };
      
      }]);
      

      使用方法:

      $scope.$on("AnyEvent", stealEvent(function (event, anyOtherParameter) {
        if ($scope.keepEvent) {
          // do some stuff with anyOtherParameter
          return true; // steal event
        } else {
          return false; // let event available for other listeners
        }
      }));
      
      $scope.$on("AnyOtherEvent", stealEvent(function (event, anyOtherParameter) {
        // do some stuff with anyOtherParameter, event stolen by default
      }));
      

      【讨论】:

        猜你喜欢
        • 2015-07-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多