following the DRY principal, i want to write a button directive which keeps button disabled for the duration of $http class.
I want to do this so as to forbid user from
This directive will disable the button until the save/promises is not fulfilled. single-click must return promises otherwise it will not disable the button.
In case there is no promises but still want to disable the button, then it is recommended to write own logic of disabling the button
app.directive('singleClick', function ($parse) {
return {
compile: function ($element, attr) {
var handler = $parse(attr.singleClick);
return function (scope, element, attr) {
element.on('click', function (event) {
scope.$apply(function () {
var promise = handler(scope, { $event: event }); /// calls and execute the function specified in attrs.
if (promise && angular.isFunction(promise.finally)) { /// will execute only if it returns any kind of promises.
element.attr('disabled', true);
promise.finally(function () {
element.attr('disabled', false);
});
}
});
});
};
}
};
});
You can create a directive that could be used on the element you want disabled.
var loadingDisabled = function ($http) {
return {
restrict: "a",
link: function (scope, elem, attr) {
scope.isLoading = function () {
return $http.pendingRequests.length > 0;
}
scope.$watch(scope.isLoading, function(v) {
if (v) {
elem.disabled = true;
} else {
elem.disabled = false;
}
});
}
};
};
You can use this in the run block. This will make sure all the buttons will be disabled whenever there is an active XHR call.
myApp.run(function($rootScope, $http) {
$http.defaults.transformRequest.push(function (data) {
$rootScope.progress = true;
return data;
});
$http.defaults.transformResponse.push(function(data){
$rootScope.progress = false;
return data;
})
});
And then use the same model anywhere you want.
<button ng-click="save()" ng-disabled="progress">Save</button>