Skip to content
This repository has been archived by the owner on Jan 9, 2023. It is now read-only.

Commit

Permalink
Revert "Using priority to make sure ngSubmit already attached its han…
Browse files Browse the repository at this point in the history
…dlers"
  • Loading branch information
johannesjo committed Mar 17, 2018
1 parent 44901be commit 2a01037
Show file tree
Hide file tree
Showing 6 changed files with 253 additions and 305 deletions.
116 changes: 47 additions & 69 deletions dist/angular-promise-buttons.js
@@ -1,7 +1,7 @@
angular.module('angularPromiseButtons', []);


angular.module('angularPromiseButtons')
.directive('promiseBtn', ['angularPromiseButtons', '$parse', '$timeout', '$compile', function (angularPromiseButtons, $parse, $timeout, $compile) {
.directive('promiseBtn', ['angularPromiseButtons', '$parse', '$timeout', '$compile', function(angularPromiseButtons, $parse, $timeout, $compile) {
'use strict';

return {
Expand All @@ -12,7 +12,7 @@ angular.module('angularPromiseButtons')
promiseBtnOptions: '=?',
ngDisabled: '=?'
},
link: function (scope, el, attrs) {
link: function(scope, el, attrs) {
// provide configuration
var cfg = angularPromiseButtons.config;
// later initialized via initPromiseWatcher()
Expand Down Expand Up @@ -61,13 +61,13 @@ angular.module('angularPromiseButtons')
*/
function initPromiseWatcher(watchExpressionForPromise, btnEl) {
// watch promise to resolve or fail
scope.$watch(watchExpressionForPromise, function (mVal) {
scope.$watch(watchExpressionForPromise, function(mVal) {
minDurationTimeoutDone = false;
promiseDone = false;

// create timeout if option is set
if (cfg.minDuration) {
minDurationTimeout = $timeout(function () {
minDurationTimeout = $timeout(function() {
minDurationTimeoutDone = true;
handleLoadingFinished(btnEl);
}, cfg.minDuration);
Expand All @@ -79,18 +79,18 @@ angular.module('angularPromiseButtons')

// angular promise
if (mVal.finally) {
mVal.finally(function () {
mVal.finally(function() {
promiseDone = true;
handleLoadingFinished(btnEl);
});
}
// ES6 promises
else {
mVal.then(function () {
promiseDone = true;
handleLoadingFinished(btnEl);
})
.catch(function () {
mVal.then(function() {
promiseDone = true;
handleLoadingFinished(btnEl);
})
.catch(function() {
promiseDone = true;
handleLoadingFinished(btnEl);
});
Expand All @@ -100,7 +100,7 @@ angular.module('angularPromiseButtons')
// for $resource
else if (mVal && mVal.$promise) {
initLoadingState(btnEl);
mVal.$promise.finally(function () {
mVal.$promise.finally(function() {
promiseDone = true;
handleLoadingFinished(btnEl);
});
Expand All @@ -115,9 +115,9 @@ angular.module('angularPromiseButtons')
*/
function getCallbacks(expression) {
return expression
// split by ; to get different functions if any
// split by ; to get different functions if any
.split(';')
.map(function (callback) {
.map(function(callback) {
// return getter function
return $parse(callback);
});
Expand All @@ -139,13 +139,13 @@ angular.module('angularPromiseButtons')
function addHandlersForCurrentBtnOnly(btnEl) {
// handle current button only options via click
if (cfg.addClassToCurrentBtnOnly) {
btnEl.on(cfg.CLICK_EVENT, function () {
btnEl.on(cfg.CLICK_EVENT, function() {
btnEl.addClass(cfg.btnLoadingClass);
});
}

if (cfg.disableCurrentBtnOnly) {
btnEl.on(cfg.CLICK_EVENT, function () {
btnEl.on(cfg.CLICK_EVENT, function() {
btnEl.attr('disabled', 'disabled');
});
}
Expand All @@ -160,59 +160,37 @@ angular.module('angularPromiseButtons')
* @param {String}attrToParse
* @param {Object}btnEl
*/
function updateHandler(eventToHandle, attrToParse, btnEl) {
function initHandlingOfViewFunctionsReturningAPromise(eventToHandle, attrToParse, btnEl) {
// we need to use evalAsync here, as
// otherwise the click or submit event
// won't be ready to be replaced
var callbacks = getCallbacks(attrs[attrToParse]);

// unbind original click event
el.off(eventToHandle);

// rebind, but this time watching it's return value
el.on(eventToHandle, function (event) {
// Make sure we run the $digest cycle
scope.$apply(function () {
callbacks.forEach(function (cb) {
// execute function on parent scope
// as we're in an isolate scope here
var promise = cb(scope.$parent, {
$event: event
});
scope.$evalAsync(function() {
var callbacks = getCallbacks(attrs[attrToParse]);

// unbind original click event
el.unbind(eventToHandle);

// rebind, but this time watching it's return value
el.bind(eventToHandle, function(event) {
// Make sure we run the $digest cycle
scope.$apply(function() {
callbacks.forEach(function(cb) {
// execute function on parent scope
// as we're in an isolate scope here
var promise = cb(scope.$parent, { $event: event });

// only init watcher if not done before
if (!promiseWatcher) {
promiseWatcher = initPromiseWatcher(function () {
return promise;
}, btnEl);
}
// only init watcher if not done before
if (!promiseWatcher) {
promiseWatcher = initPromiseWatcher(function() {
return promise;
}, btnEl);
}
});
});
});
});
}

/**
* Used for the function syntax of the promise button directive by
* parsing the expressions provided by the attribute via getCallbacks().
* Unbinds the default event handlers, which is why it might sometimes
* be required to use the promise syntax.
*
* @param {String}eventToHandle the event to handle
* @param {String}attrToParse the attribute to parse the callback from (ngClick or ngSubmit)
* @param {Object}btnEl the button element to disable and add spinner
*/
function initHandlingOfViewFunctionsReturningAPromise(eventToHandle, attrToParse, btnEl) {
// If the priority is higher then zero, we are sure that ngSubmit already attached the event handler,
// if not, then we need to execute with $evalAsync
if (cfg.priority > 0) {
updateHandler(eventToHandle, attrToParse, btnEl);
} else {
scope.$evalAsync(function () {
updateHandler(eventToHandle, attrToParse, btnEl);
});
}
}

/**
* Get's all submit button children of the given element
* @param {Object}formEl
Expand All @@ -225,7 +203,7 @@ angular.module('angularPromiseButtons')
for (var i = 0; i < allButtonEls.length; i++) {
var btnEl = allButtonEls[i];
if (angular.element(btnEl)
.attr('type') === 'submit') {
.attr('type') === 'submit') {
submitBtnEls.push(btnEl);
}
}
Expand Down Expand Up @@ -258,26 +236,26 @@ angular.module('angularPromiseButtons')
appendSpinnerTpl(el);
addHandlersForCurrentBtnOnly(el);
// handle promise passed directly via attribute as variable
initPromiseWatcher(function () {
initPromiseWatcher(function() {
return scope.promiseBtn;
}, el);
}

// watch and update options being changed
scope.$watch('promiseBtnOptions', function (newVal) {
scope.$watch('promiseBtnOptions', function(newVal) {
if (angular.isObject(newVal)) {
cfg = angular.extend({}, cfg, newVal);
}
}, true);

// cleanup
scope.$on('$destroy', function () {
scope.$on('$destroy', function() {
$timeout.cancel(minDurationTimeout);
});
}
};
}]);


angular.module('angularPromiseButtons')
.provider('angularPromiseButtons', function angularPromiseButtonsProvider() {
'use strict';
Expand All @@ -288,7 +266,7 @@ angular.module('angularPromiseButtons')

var config = {
spinnerTpl: '<span class="btn-spinner"></span>',
priority: 10,
priority: 0,
disableBtn: true,
btnLoadingClass: 'is-loading',
addClassToCurrentBtnOnly: false,
Expand All @@ -310,19 +288,19 @@ angular.module('angularPromiseButtons')
// *************************

return {
extendConfig: function (newConfig) {
extendConfig: function(newConfig) {
config = angular.extend(config, newConfig);
},

// ************************************************
// ACTUAL FACTORY FUNCTION - used by the directive
// ************************************************

$get: function () {
$get: function() {
return {
config: config
};
}
};
});

2 changes: 1 addition & 1 deletion dist/angular-promise-buttons.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions src/angular-promise-buttons-p.js
Expand Up @@ -8,7 +8,7 @@ angular.module('angularPromiseButtons')

var config = {
spinnerTpl: '<span class="btn-spinner"></span>',
priority: 10,
priority: 0,
disableBtn: true,
btnLoadingClass: 'is-loading',
addClassToCurrentBtnOnly: false,
Expand All @@ -30,15 +30,15 @@ angular.module('angularPromiseButtons')
// *************************

return {
extendConfig: function (newConfig) {
extendConfig: function(newConfig) {
config = angular.extend(config, newConfig);
},

// ************************************************
// ACTUAL FACTORY FUNCTION - used by the directive
// ************************************************

$get: function () {
$get: function() {
return {
config: config
};
Expand Down

0 comments on commit 2a01037

Please sign in to comment.