我怎样才能使AngularJS指令stopPropagation?


76

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

在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定义的click事件,但是您尝试使用jQuery停止事件传播。
Josh David Miller

Answers:


156

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

    .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'>

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


顺便说一句,您能详细介绍一下restrict关键字吗?找不到确切含义的优质资源。
罗伯特·克里斯蒂安

当然!docs.angularjs.org/guide/directive “指令定义对象”:strict -EACM子集的字符串,它将指令限制为特定的指令声明样式。如果省略,则仅在属性上允许使用伪指令。
Valentyn Shybanov

这是一种有趣的方法...我喜欢。谢谢!
incutonez 2013年

1
IE7中.prefentDefault()的相同解决方案,以防止重新加载页面。很好的解决方案!
Malkus

1
哦,上帝,我爱指令
Deminetix

123

“当前一些指令(即ng:click)停止事件传播。这阻止了与依赖于捕获此类事件的其他框架的互操作性。” -链接

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

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

4
太完美了 我有一个带有表单的下拉菜单。我在表单周围的div上添加了ng-click =“ $ event.stopPropagation()”,并修复了单击表单输入后下拉菜单不会消失的问题。谢谢!
thaspius

简单的解决方案。工作完美。我宁愿这样做而不是创建指令。
Nithin Emmanuel 2014年

确实,比必须创建指令要简单。对我来说很好。谢谢
estellechvl 2014年

3
一次性使用场景简单。我建议向需要在整个视图中的多个位置使用此代码的任何人使用一个指令-其中之一是,它更易于扩展功能,处理更多事件,尤其是尽量避免将逻辑超出标记范围可能。干杯!
Danny Bullis

如果我们单击另一个按钮,则该策略不起作用。链接不会关闭。当前链接未关闭
Saurabh 2015年

9

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
罗伯特·克里斯蒂安

因此找到了解决方法:<a ng-click="doThing($index); $event.stopPropagation();"> x </a>
Robert Christian

1

这是停止事件传播的简单抽象指令。我认为这对某人可能有用。只需传递您想要停止的事件即可。

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

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


2
那不是必须包含stop-prop在元素中吗?
皮特
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.