javascript - Angular.js, cancel ng-click event - Stack Overflow

admin2025-04-18  1

I have this piece of html

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

and a bit of JavaScript

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

Now, what I'm trying to do, is to cancel the ng:click event, from within the directive. But the ng:click still get's triggered, no matter what I do.

Demo: Fiddle

Edit: By the way, causing an error within the this scope:

element.bind('click.confirm', function(event)
{
    causeAnError();
    event.preventDefault();
    event.stopPropagation();
});

Does the trick, and canceles the event propagation, but also throws and ugly error =)

Edit 2: Finally I've found a solution!

.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!
            });
        }
    }
})

Edit 3:

FINAL SOLUTION

.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');
        }
    }
})

Clicking a button the first time, gonna make it red, and doesn't trigger any action. Clicking a second time, calls the action. Leaving the button resets the whole process.

I have this piece of html

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

and a bit of JavaScript

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

Now, what I'm trying to do, is to cancel the ng:click event, from within the directive. But the ng:click still get's triggered, no matter what I do.

Demo: Fiddle

Edit: By the way, causing an error within the this scope:

element.bind('click.confirm', function(event)
{
    causeAnError();
    event.preventDefault();
    event.stopPropagation();
});

Does the trick, and canceles the event propagation, but also throws and ugly error =)

Edit 2: Finally I've found a solution!

.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!
            });
        }
    }
})

Edit 3:

FINAL SOLUTION

.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');
        }
    }
})

Clicking a button the first time, gonna make it red, and doesn't trigger any action. Clicking a second time, calls the action. Leaving the button resets the whole process.

Share edited Jan 1, 2014 at 1:34 M K asked Mar 13, 2013 at 12:53 M KM K 9,4267 gold badges45 silver badges45 bronze badges 5
  • 1 @Arun P Johny - thank you for the Fiddle!! – M K Commented Mar 13, 2013 at 13:19
  • what you are trying to do may be related to this groups.google./forum/#!msg/angular/ADylKzNT5oI/n6ZagosZZgsJ – Arun P Johny Commented Mar 13, 2013 at 13:24
  • @ArunPJohny I've already seen this, but it's another scenario. – M K Commented Mar 13, 2013 at 13:27
  • What does bind('click.confirm') do? I haven't seen that before. – Mark Rajcok Commented Mar 13, 2013 at 16:34
  • 1 click = event, confirm = namespace – M K Commented Mar 13, 2013 at 18:09
Add a ment  | 

2 Answers 2

Reset to default 2

As discussed in the ments on @Flek's answer, to call a function defined in an attribute,

ui:confirm="action()"

use scope.$eval():

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

You have two nested directives:

  1. uiConfirm
  2. ngClick

You then bind two event handlers to it (one by uiConfirm and the other one by ngClick). With preventDefault you want to stop the default action but I guess the default action of a button is not calling the action() method. stopPropagation just prevents the event from bubbling up the DOM tree but since you only care about the button itself it doesn't change anything.

What I would do is to create a custom action method within the directive and then check whether it should do something or not.

.directive('uiConfirm', function()
{
    return {
        restrict: 'A',
        link: function(scope, element, attrs)
        {
            scope.action = function(){
                // Check whether there is something to do or not.
            };
        }
    }
})
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1744925270a274809.html

最新回复(0)