UNPKG

angular-filter

Version:

Bunch of useful filters for angularJS(with no external dependencies!)

149 lines (135 loc) 3.93 kB
/** * @ngdoc provider * @name filterWatcher * @kind function * * @description * store specific filters result in $$cache, based on scope life time(avoid memory leak). * on scope.$destroy remove it's cache from $$cache container */ angular.module('a8m.filter-watcher', []) .provider('filterWatcher', function() { this.$get = ['$window', '$rootScope', function($window, $rootScope) { /** * Cache storing * @type {Object} */ var $$cache = {}; /** * Scope listeners container * scope.$destroy => remove all cache keys * bind to current scope. * @type {Object} */ var $$listeners = {}; /** * $timeout without triggering the digest cycle * @type {function} */ var $$timeout = $window.setTimeout; /** * @description * get `HashKey` string based on the given arguments. * @param fName * @param args * @returns {string} */ function getHashKey(fName, args) { function replacerFactory() { var cache = []; return function(key, val) { if(isObject(val) && !isNull(val)) { if (~cache.indexOf(val)) return '[Circular]'; cache.push(val) } if($window == val) return '$WINDOW'; if($window.document == val) return '$DOCUMENT'; if(isScope(val)) return '$SCOPE'; return val; } } return [fName, JSON.stringify(args, replacerFactory())] .join('#') .replace(/"/g,''); } /** * @description * fir on $scope.$destroy, * remove cache based scope from `$$cache`, * and remove itself from `$$listeners` * @param event */ function removeCache(event) { var id = event.targetScope.$id; forEach($$listeners[id], function(key) { delete $$cache[key]; }); delete $$listeners[id]; } /** * @description * for angular version that greater than v.1.3.0 * it clear cache when the digest cycle is end. */ function cleanStateless() { $$timeout(function() { if(!$rootScope.$$phase) $$cache = {}; }, 2000); } /** * @description * Store hashKeys in $$listeners container * on scope.$destroy, remove them all(bind an event). * @param scope * @param hashKey * @returns {*} */ function addListener(scope, hashKey) { var id = scope.$id; if(isUndefined($$listeners[id])) { scope.$on('$destroy', removeCache); $$listeners[id] = []; } return $$listeners[id].push(hashKey); } /** * @description * return the `cacheKey` or undefined. * @param filterName * @param args * @returns {*} */ function $$isMemoized(filterName, args) { var hashKey = getHashKey(filterName, args); return $$cache[hashKey]; } /** * @description * store `result` in `$$cache` container, based on the hashKey. * add $destroy listener and return result * @param filterName * @param args * @param scope * @param result * @returns {*} */ function $$memoize(filterName, args, scope, result) { var hashKey = getHashKey(filterName, args); //store result in `$$cache` container $$cache[hashKey] = result; // for angular versions that less than 1.3 // add to `$destroy` listener, a cleaner callback if(isScope(scope)) { addListener(scope, hashKey); } else { cleanStateless(); } return result; } return { isMemoized: $$isMemoized, memoize: $$memoize } }]; });