(function () { "use strict"; var name = 'adAutosave'; angular.module('app.directive') .constant('adAutosaveConfig', { timeout: 750 }) /** * ad-autosave="onSave" {Function: promise} * ad-autosave-timeout="750" {?Number} override adAutosaveConfig.timeout */ .directive('adAutosave', ['$parse', 'adAutosaveConfig', 'debounce', function ($parse, adAutosaveConfig, debounce) { return { require: 'ngModel', link: function (scope, element, attr, ctrl) { var getAttrReflection = function (name, defValue) { var exprDefined = angular.isDefined(attr[name]), expr; if (exprDefined || angular.isDefined(defValue)) { expr = exprDefined ? $parse(attr[name]) : null; return function (locals) { return expr ? expr(scope, locals) : defValue; }; } return null; }; var attrAutosave = getAttrReflection(name); var timeout = getAttrReflection(name + 'Timeout', adAutosaveConfig.timeout)(); ctrl.$autosaving = false; ctrl.$autosaveValue = ctrl.$modelValue; var autosaveStart = function () { ctrl.$autosaving = true; ctrl.$autosaveValue = ctrl.$modelValue; }; var autosaveDone = function () { ctrl.$autosaving = false; ctrl.$setPristine(); }; var triggerSave = function () { var promise; if (ctrl.$valid && ctrl.$dirty && ctrl.$modelValue !== ctrl.$autosaveValue) { autosaveStart(); promise = attrAutosave({value: ctrl.$modelValue}); if (promise && angular.isFunction(promise.then)) { promise.then(autosaveDone, autosaveDone); } } }; (timeout && timeout > 0) && ctrl.$viewChangeListeners.push(debounce(triggerSave, timeout)); element.on('blur', triggerSave); element.on('$destroy', element.off.bind(element, 'blur', triggerSave)); } }; }]); })();