In my angular app, I wanted to disable a button during a REST api request, my first solution was to add an ngDisabled directive bind to a boolean I set manually.

It worked well but I found a better way to do that with a custom directive:

app.directive('disableOnPromise', function ($parse) {
    return {
        restrict: 'A',
        compile: function($element, attr) {
            var fn = $parse(attr.disableOnPromise);
            return function clickHandler(scope, element, attrs) {
                element.on('click', function(event) {
                    attrs.$set('disabled', true);
                    scope.$apply(function() {
                        fn(scope, {$event:event}).finally(function() {
                            attrs.$set('disabled', false);
                        });
                    });
                });
            };
        }
    };
});

The second solution is better because you don’t pollute your controller with a boolean only used for the view and it’s one watcher less for each time you use it.

However, to use it, a promise have to be returned in your save function. Restangular does by default or you can create one with $q.

View it in action:

[Edit] New version using Ladda Bootstrap:

I did this experiment few months ago to prepare me to the next feature I was going to implement at job.

This is a recursive table, a main group can contain criterions, segments and others groups and the same for all others groups inside.

Demo:

Or you can clone this repository: https://github.com/bertrandg/recursive-directive

Production version:

You can test the production version here: this-is-big.com

This version is more complexe because all changes are instantly saved and some others things..

this-is-big.com - Segment builder

Next step:

Next, I’m gonna add the drag & drop feature between element inside a same groug and then accross level.