JSFiddle - React, Tailwind, and code Playground

HTML

<div ng-app="Module" ng-controller="TestCtrl">
    <a href="" single-click="test()">{{ running ? 'Please wait...' : 'Click me!' }}</a>
</div>

CSS

.state-waiting {
    color: grey;
}

JavaScript

var Module = angular.module('Module', []);

Module.controller('TestCtrl', [ '$scope', '$timeout', function ($scope, $timeout) {
    $scope.test = function() {
        console.log('starting action...');
        return $timeout(function() { 
            console.log('done!');
         // imitate long running action
        }, 2000);
    }
}]);

Module.directive("singleClick", ['$parse',
function($parse) {
    return {
        restrict: 'A',
        scope: true,
        compile: function ($element, attr) {
            var fn = $parse(attr.singleClick);
            return function(scope, element) {
                scope.running = false;

                element.on("click", function (event) {
                    scope.$apply(function () {
                        if(!scope.running) {
                            var result = fn(scope, { $event: event });
                            if(!!result && result.finally !== undefined) {
                                scope.running = true;
                                element.addClass('state-waiting');
                                result.finally(function () {
                                    element.removeClass('state-waiting');
                                    scope.running = false;
                                });
                            }
                        }
                    });
                });
            };
        }
    };
}]);