Angular.js,取消ng-click事件

4

我有这段html代码

<button ui:confirm ng:click="action"></button>

还有一点 JavaScript。

.directive('uiConfirm', function()
{
    return {
        restrict: 'A',
        link: function(scope, element, attrs)
        {
            element.bind('click.confirm', function(event)
            {
                event.preventDefault();
                event.stopPropagation();
            });
        }
    }
})

现在,我的目标是在指令内部取消 ng:click 事件。但无论我做什么,ng:click 仍然会被触发。
演示:Fiddle 编辑: 顺便说一句,在这个作用域中引起错误:
element.bind('click.confirm', function(event)
{
    causeAnError();
    event.preventDefault();
    event.stopPropagation();
});

完成了操作,取消了事件传播,但也产生了一个难看的错误 =)

编辑2:最终我找到了一个解决方案!

.directive('uiConfirm', function()
{
    return {
        restrict: 'A',
        link: function(scope, element, attrs)
        {
            element.bind('click', function(event)
            {
                scope.$eval(attrs.uiConfirm); // this line of code does the magic!
            });
        }
    }
})

编辑3:

最终解决方案

.directive('uiConfirm', function()
{
    return {
        restrict: 'A',
        link: function(scope, element, attrs)
        {
            /**
             * Clicking the trigger start the confirmation process.
             */
            element.bind('click.confirm', function(event)
            {
                // not confirmed?
                if( ! element.data().confirmed)
                {
                    element.data().confirmed = true;
                    element.addClass('btn-danger');
                }
                // is already confirmed..
                else
                {
                    element.trigger('mouseout.confirm');
                    scope.$eval(attrs.uiConfirm);
                }
            });

            /**
             * Leaving the element, resets the whole process.
             */
            element.bind('mouseout.confirm', function()
            {
                // reset all values
                element.data().confirmed = false;
                element.removeClass('btn-danger');
            });

            // reset the whole process on the first run
            element.trigger('mouseout.confirm');
        }
    }
})

第一次点击按钮会将其变成红色,并且不会触发任何动作。第二次点击会调用操作。离开按钮会重置整个过程。


1
@Arun P Johny - 谢谢你提供的 Fiddle! - M K
你所尝试的可能与这个相关:https://groups.google.com/forum/#!msg/angular/ADylKzNT5oI/n6ZagosZZgsJ - Arun P Johny
@ArunPJohny 我已经看过这个了,但是那是另一种情况。 - M K
bind('click.confirm') 做了什么?我以前没有见过。 - Mark Rajcok
1
点击 = 事件, 确认 = 命名空间 - M K
2个回答

2

如在@Flek的答案评论中所讨论的,要调用在属性中定义的函数,

ui:confirm="action()"

使用 scope.$eval()

element.bind('click', function(event) {
    scope.$eval(attrs.uiConfirm);  // calls action() on the scope
});

1
从Angular 1.2.0-rc.3开始,你应该使用scope.$apply(),这样任何影响作用域的操作都会显示出来... - JustMaier
我正在使用Angular 1.3.15,但它无法阻止ng-click的执行。 - Alex Coroza

1

您有两个嵌套指令:

  1. uiConfirm
  2. ngClick

您可以通过这两个事件处理程序绑定两个事件(一个由uiConfirm,另一个由ngClick)。 使用preventDefault可以停止默认操作,但我猜按钮的默认操作不是调用action()方法。 stopPropagation只是阻止事件从DOM树中冒泡,但由于您只关心按钮本身,它不会改变任何内容。

我建议在指令中创建自定义操作方法,然后检查它是否应该执行某些操作。

.directive('uiConfirm', function()
{
    return {
        restrict: 'A',
        link: function(scope, element, attrs)
        {
            scope.action = function(){
                // Check whether there is something to do or not.
            };
        }
    }
})

假设我使用ui:confirm代替ng:click,它将是ng:click和以前的ui:confirm的混合体。但是,我该如何在指令内部评估传递给指令的函数呢? ui:confirm =“action()”-> 在指令中,它只是一个简单的字符串,而不是一个函数。 - M K
1
@maximkott,scope.$eval(attrs.uiConfirm) - Mark Rajcok
@MarkRajcok 我会尝试这个,稍后会把结果发给你) - M K
@MarkRajcok 哥们,这个方法太棒了!快发一个真正的答案,这样我就可以给你一个“采纳”了。干杯! - M K
这个解决方案比被接受的答案好多了。 - itsafire

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