如何在AngularJS中的自定义指令中阻止ng-click事件?

4
请看下面的myButton指令:

演示实例

angular.module("Demo", []).directive("myButton", function() {
  return {
    restrict : "E",
    replace: true,
    scope: {
      disabled: "="
    },
    transclude: true,
    template: "<div class='my-button' ng-class='{ \"my-button-disabled\": disabled }' ng-transclude></div>",
  };
});

以下是可以这样使用的方法:

<my-button disabled="buttonIsDisabled" 
           ng-click="showSomething = !showSomething">
  Toggle Something
</my-button>

buttonIsDisabledtrue时,我该如何阻止ng-click执行?

点此查看示例


2
如果您不使用内置的 ng-disabled,那么您可能也不想使用内置的 ng-click - lyschoening
2
实际上,无论是 disabled 还是由 disabled 支持的 ngDisabled 在这里都没有任何效果,因为它们被放置在一个 div 上(而不是一个 inputbutton)。 - gkalpak
4个回答

5
你可以使用 capture(addEventListener 的可选第三个参数),并使用 stopPropagation 来阻止事件的传播。 "Capture" 允许你在事件到达“冒泡”阶段之前(当触发“正常”事件监听器时)捕获事件,“stopPropagation” 将停止事件的传播(因此它永远不会到达冒泡阶段)。
element[0].addEventListener('click', function (evt) {
    if (scope.disabled) {
        console.log('Stopped ng-click here');
        evt.preventDefault();
        evt.stopPropagation();
    }
}, true);

另外,还可以参考这个 简短的演示


谢谢!一个问题:这里真的需要 event.preventDefault(); 吗? - Misha Moroshko
你抓住我了 :) 没有它似乎也能正常工作,但是1.) 它不会有任何影响,2.) 我觉得这样可以使代码更具声明性(即更容易理解该块的目的是取消事件)。 - gkalpak
捕获阶段在IE上不受支持,因此它将无法跨浏览器。 - Armen

2

为什么不使用真正的按钮来作为你的按钮。你可以将指令更改为:

angular.module("Demo", []).directive("myButton", function() {
  return {
    restrict : "E",
    replace: true,
    scope: {
      disabled: "="
    },
    transclude: true,
    template: "<button class='my-button' ng-class='{ \"my-button-disabled\": disabled }' ng-disabled='disabled' type='button' ng-transclude></button>"
  };
});

然后将其样式设置为与您的div相同。请参见我制作的简短示例

1
在您的链接函数中尝试这个:

link: function(scope, element, attrs) {
      var clickHandlers = $._data(element[0]).events.click;

      clickHandlers.reverse(); //reverse the click event handlers list

      element.on('click', function(event) {
        if (scope.disabled) {
          event.stopImmediatePropagation(); //use stopImmediatePropagation() instead of stopPropagation()
        }
      });

      clickHandlers.reverse(); //reverse the list again to make our function at the head of the list
}

演示

这个解决方案使用jQuery来处理跨浏览器问题。这里的思路是将我们的事件处理程序附加在点击处理程序列表的头部,并使用stopImmediatePropagation()来停止相同事件的当前处理程序和冒泡事件。

还可以看看这个:jquery: stopPropagation vs stopImmediatePropagation


0
<my-button disabled="buttonIsDisabled" 
       ng-click="showSomething = buttonIsDisabled ? showSomething : !showSomething">

或者

<my-button disabled="buttonIsDisabled" 
       ng-click="showSomething = buttonIsDisabled ? function(){} : !showSomething">

这个太简单了吗?


1
据我理解,这个问题是关于如何停止在指令中使用 ng-click,以便我们不需要在每个使用该指令的地方都添加这个逻辑。 - Khanh TO

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接