/// crmUi: Sundry UI helpers
(function (angular, $, _) {
- angular.module('crmUtil', []);
+ angular.module('crmUtil', CRM.angRequires('crmUtil'));
// Angular implementation of CRM.api3
// @link http://wiki.civicrm.org/confluence/display/CRMDOC/AJAX+Interface#AJAXInterface-CRM.api3
};
});
+ // Run a given function. If it is already running, wait for it to finish before running again.
+ // If multiple requests are made before the first request finishes, all but the last will be ignored.
+ // This prevents overwhelming the server with redundant queries during e.g. an autocomplete search while the user types.
+ // Given function should return an angular promise. crmThrottle will deliver the contents when resolved.
+ angular.module('crmUtil').factory('crmThrottle', function($q) {
+ var pending = [],
+ executing = [];
+ return function(func) {
+ var deferred = $q.defer();
+
+ function checkResult(result, success) {
+ _.pull(executing, func);
+ if (_.includes(pending, func)) {
+ runNext();
+ } else if (success) {
+ deferred.resolve(result);
+ } else {
+ deferred.reject(result);
+ }
+ }
+
+ function runNext() {
+ executing.push(func);
+ _.pull(pending, func);
+ func().then(function(result) {
+ checkResult(result, true);
+ }, function(result) {
+ checkResult(result, false);
+ });
+ }
+
+ if (!_.includes(executing, func)) {
+ runNext();
+ } else if (!_.includes(pending, func)) {
+ pending.push(func);
+ }
+ return deferred.promise;
+ };
+ });
+
})(angular, CRM.$, CRM._);