如何制作 AngularJS 指令来停止传播?

Posted

技术标签:

【中文标题】如何制作 AngularJS 指令来停止传播?【英文标题】:How can I make an AngularJS directive to stopPropagation? 【发布时间】:2013-01-10 18:29:47 【问题描述】:

我正在尝试“stopPropagation”以防止在单击 li 内的元素(链接)时关闭 Twitter Bootstrap 导航栏下拉菜单。使用这种方法似乎是常见的solution。

在 Angular 中,似乎指令是执行此操作的地方?所以我有:

// do not close dropdown on click
directives.directive('stopPropagation', function () 
    return 
        link:function (elm)             
            $(elm).click(function (event)                 
                event.stopPropagation();
            );
        
    ;
);

...但是方法不属于元素:

TypeError: Object [object Object] has no method 'stopPropagation'

我将指令与

联系起来
<li ng-repeat="foo in bar">
  <div>
    foo.text<a stop-propagation ng-click="doThing($index)">clickme</a>
  </div>
</li>

有什么建议吗?

【问题讨论】:

你应该在标签中为javascript(甚至jquery)腾出一些空间。 好建议。进行了编辑。 event.stopPropagation() 在您的代码中不起作用的原因是 AngularJS 和 jQuery 有两个独立的事件循环。这就是为什么同时使用它们通常是个坏主意的原因之一。您使用 ngClick 定义的点击事件使用 Angular,但您正尝试使用 jQuery 来停止事件传播。 【参考方案1】:

我用过这种方式:创建了一个指令:

    .directive('stopEvent', function () 
        return 
            restrict: 'A',
            link: function (scope, element, attr) 
                if(attr && attr.stopEvent)
                    element.bind(attr.stopEvent, function (e) 
                        e.stopPropagation();
                    );
            
        ;
     );

可以这样使用:

<a ng-click='expression' stop-event='click'>

这是停止任何类型事件传播的更通用的方法。

【讨论】:

顺便说一句,你能详细说明一下限制关键字吗?没有找到一个很好的资源来说明这究竟意味着什么。 当然! docs.angularjs.org/guide/directive“指令定义对象”:restrict - EACM 子集的字符串,它将指令限制为特定指令声明样式。如果仅在属性上允许省略指令。 这是一个有趣的方法......我喜欢它。谢谢! 与 .preventDefault() 在 IE7 中的解决方案相同,以防止页面重新加载。很好的解决方案! 天哪,我喜欢指令【参考方案2】:

“目前某些指令(例如 ng:click)会停止事件传播。这会妨碍与依赖捕获此类事件的其他框架的互操作性。” - link

... 并且能够在没有指令的情况下进行修复,并且只需执行以下操作:

<a ng-click="doThing($index); $event.stopPropagation();">x</a>

【讨论】:

这太完美了。我有一个下拉列表,里面有一个表格。我将 ng-click="$event.stopPropagation()" 添加到表单周围的 div 中,并修复了单击表单输入时下拉菜单消失的问题。谢谢! 简单的解决方案。完美地工作。我更喜欢这个而不是创建一个指令。 确实,比必须创建指令更简单。对我来说很好。谢谢 简单的单次使用场景。对于需要在整个视图中的多个位置使用此代码的任何人,我建议使用指令 - 一方面,扩展功能更容易,处理更多事件,尤其是尽量将逻辑排除在标记之外可能的。干杯! 如果我们点击另一个按钮,链接这个策略不起作用。当前链接不会被关闭【参考方案3】:

stopPropagation 必须在事件对象上调用,而不是元素本身。这是一个例子:

compile: function (elm) 
    return function (scope, elm, attrs) 
        $(elm).click(function (event) 
            event.stopPropagation();
        );
    ;

【讨论】:

谢谢。我编辑了问题,以便指令在事件而不是元素上调用 stopPropagation。没用。发现这个:“目前一些指令(即 ng:click)停止事件传播。这阻止了与依赖捕获此类事件的其他框架的互操作性。” - github.com/angular/angular.js/issues/259 所以发现这是解决方法:x【参考方案4】:

这是一个用于停止事件传播的简单抽象指令。我认为它可能对某人有用。只需传递您希望停止的事件即可。

<div stopProp="click"></div>

app.directive('stopProp', function () 
  return function (scope, elm, attrs) 
    elm.on(attrs.stopProp, function (event) 
        event.stopPropagation();
    );
  ;
);

【讨论】:

元素中不需要stop-prop吗?

以上是关于如何制作 AngularJS 指令来停止传播?的主要内容,如果未能解决你的问题,请参考以下文章

浅谈AngularJS中的指令和指令间的相互通信

防止默认和停止传播不使用pointermove

如何将一些 jQuery 函数转换为 angularjs 指令?

AngularJS 指令需要观察两个属性

需要 angularjs-dragula 包时未加载 angularjs 指令

D3.js 4 与 AngularJS 1.5(组件或指令?)