This is an attempt to put the tree cache into sessionStorage - I'm creating this revision in case we want to re-visit this but unfortunately it is much more difficult because the cache is serialized/deserialized which means only the first level will be cached automatically since the loadNodeChildren would have to update the cache too but it doesn't know what a cache key is.

I've then done it the other way which is that we cache the tree sections when changing sections, this works great but poses other issues due to the serialized nature of the tree nodes. Spending too much time here, will revisit some other day. will revert after this is committed.
This commit is contained in:
Shannon
2013-11-12 15:02:02 +11:00
parent 72b08f4029
commit c2fca795e6
3 changed files with 84 additions and 29 deletions

View File

@@ -217,7 +217,11 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat
//anytime we want to load the tree we need to disable the delete animations
deleteAnimations = false;
//use $q.when because a promise OR raw data might be returned.
//Here's where we cache the data before loading other data (changing sections)
if (lastSection && scope.section !== lastSection) {
treeService.cacheTree(scope.cachekey, lastSection, scope.tree);
}
treeService.getTree({ section: scope.section, tree: scope.treealias, cacheKey: scope.cachekey, isDialog: scope.isdialog ? scope.isdialog : false })
.then(function(data) {
//set the data once we have it
@@ -356,7 +360,7 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat
//When the user logs in
scope.$on("authenticated", function(evt, data) {
//populate the tree if the user has changed
if (data.lastUserId !== data.user.id) {
if (data.lastUserId && data.lastUserId !== data.user.id) {
treeService.clearCache();
scope.tree = null;

View File

@@ -7,14 +7,13 @@
* @description
* The tree service factory, used internally by the umbTree and umbTreeItem directives
*/
function treeService($q, treeResource, iconHelper, notificationsService, $rootScope) {
function treeService($q, treeResource, iconHelper, notificationsService, $rootScope, umbSessionStorage) {
//SD: Have looked at putting this in sessionStorage (not localStorage since that means you wouldn't be able to work
// in multiple tabs) - however our tree structure is cyclical, meaning a node has a reference to it's parent and it's children
// which you cannot serialize to sessionStorage. There's really no benefit of session storage except that you could refresh
// a tab and have the trees where they used to be - supposed that is kind of nice but would mean we'd have to store the parent
// as a nodeid reference instead of a variable with a getParent() method.
var treeCache = {};
//initialize the tree cache if nothing is there, we store the cache in sessionStorage which
// is applicable to the current open tab
if (!umbSessionStorage.get("treeCache")) {
umbSessionStorage.set("treeCache", {});
}
var standardCssClass = 'icon umb-tree-icon sprTree';
@@ -31,9 +30,44 @@ function treeService($q, treeResource, iconHelper, notificationsService, $rootSc
return {
/** Internal method to return the tree cache */
_getTreeCache: function() {
return treeCache;
/** Internal method to return the tree cache - this also wires up the parent() function for each node since when we serialize to cache, functions are obviously lost */
_getTreeCache: function(key) {
var cache = umbSessionStorage.get("treeCache");
//method to set the parent() delegate for each node
var setParent = function (currParent, currChildren) {
_.each(currChildren, function (child, index) {
//create the method, return it's parent
child.parent = function () {
return currParent;
};
if (angular.isArray(child.children) && child.children.length > 0) {
//recurse
setParent(child, child.children);
}
});
};
//return the raw cache if a key is specified but there is nothing to process with that key
if (key && (!cache[key] || !cache[key].root || !angular.isArray(cache[key].root.children))) {
return cache;
}
else if (key && cache[key]) {
//if a key is specified only process that portion of the cache
setParent(cache[key].root, cache[key].root.children);
return cache;
}
else {
//no key is specified, process all of the cache
_.each(cache, function (val) {
if (val.root && angular.isArray(val.root.children)) {
setParent(val.root, val.root.children);
}
});
return cache;
}
},
/** Internal method that ensures there's a routePath, parent and level property on each tree node and adds some icon specific properties so that the nodes display properly */
@@ -121,18 +155,35 @@ function treeService($q, treeResource, iconHelper, notificationsService, $rootSc
return undefined;
},
/** This puts the tree into cache */
cacheTree: function (cacheKey, section, tree) {
if (!cacheKey || !section || !tree) {
return;
}
var key = getCacheKey({ cacheKey: cacheKey, section: section });
//NOTE: we're not using the _getTreeCache method here because we don't want to process the parent() method,
// simply to get the raw values so we can update it.
var rawCache = umbSessionStorage.get("treeCache");
rawCache[key] = tree;
umbSessionStorage.set("treeCache", rawCache);
},
/** clears the tree cache - with optional cacheKey, optional section or optional filter */
clearCache: function (args) {
//clear all if not specified
if (!args) {
treeCache = {};
umbSessionStorage.set("treeCache", {});
}
else {
var treeCache = this._getTreeCache();
//if section and cache key specified just clear that cache
if (args.section && args.cacheKey) {
var cacheKey = getCacheKey(args);
var cacheKey = getCacheKey(args);
if (cacheKey && treeCache && treeCache[cacheKey] != null) {
treeCache = _.omit(treeCache, cacheKey);
umbSessionStorage.set("treeCache", _.omit(treeCache, cacheKey));
}
}
else if (args.childrenOf) {
@@ -170,12 +221,12 @@ function treeService($q, treeResource, iconHelper, notificationsService, $rootSc
if (result) {
//set the result to the filtered data
treeCache[args.cacheKey] = result;
umbSessionStorage.set("treeCache", treeCache);
}
else {
//remove the cache
treeCache = _.omit(treeCache, args.cacheKey);
umbSessionStorage.set("treeCache", _.omit(treeCache, args.cacheKey));
}
}
}
@@ -185,7 +236,7 @@ function treeService($q, treeResource, iconHelper, notificationsService, $rootSc
var toRemove1 = _.filter(allKeys1, function (k) {
return k.startsWith(args.cacheKey + "_");
});
treeCache = _.omit(treeCache, toRemove1);
umbSessionStorage.set("treeCache", _.omit(treeCache, toRemove1));
}
else if (args.section) {
//if only the section is specified then clear all cache regardless of cache key by that section
@@ -193,7 +244,7 @@ function treeService($q, treeResource, iconHelper, notificationsService, $rootSc
var toRemove2 = _.filter(allKeys2, function (k) {
return k.endsWith("_" + args.section);
});
treeCache = _.omit(treeCache, toRemove2);
umbSessionStorage.set("treeCache", _.omit(treeCache, toRemove2));
}
}
},
@@ -347,7 +398,8 @@ function treeService($q, treeResource, iconHelper, notificationsService, $rootSc
}
var cacheKey = getCacheKey(args);
var treeCache = this._getTreeCache(cacheKey);
//return the cache if it exists
if (cacheKey && treeCache[cacheKey] !== undefined) {
deferred.resolve(treeCache[cacheKey]);
@@ -366,12 +418,13 @@ function treeService($q, treeResource, iconHelper, notificationsService, $rootSc
//we need to format/modify some of the node data to be used in our app.
self._formatNodeDataForUseInUI(result.root, result.root.children, args.section);
//cache this result if a cache key is specified - generally a cache key should ONLY
// be specified for application trees, dialog trees should not be cached.
if (cacheKey) {
treeCache[cacheKey] = result;
deferred.resolve(treeCache[cacheKey]);
}
////cache this result if a cache key is specified - generally a cache key should ONLY
//// be specified for application trees, dialog trees should not be cached.
//if (cacheKey) {
// treeCache[cacheKey] = result;
// umbSessionStorage.set("treeCache", treeCache);
// deferred.resolve(treeCache[cacheKey]);
//}
//return un-cached
deferred.resolve(result);

View File

@@ -17,9 +17,7 @@ function umbSessionStorage($window) {
return {
get: function (key) {
console.log(storage);
console.log(storage["umb_" + key]);
get: function (key) {
return angular.fromJson(storage["umb_" + key]);
},