Tree syncing optimized

Tree now syncs new trees, and also takes the delayed tree-load + iframe
loading into account on legacy editors.
This commit is contained in:
perploug
2013-11-01 09:28:12 +01:00
parent e97bb0b354
commit 31c7af1737

View File

@@ -56,9 +56,15 @@ angular.module("umbraco.directives")
//keeps track of the currently active tree being called by editors syncing
var activeTree;
//setup a default internal handler
if(!scope.eventhandler){
scope.eventhandler = $({});
}
//flag to enable/disable delete animations
var enableDeleteAnimations = false;
/** Helper function to emit tree events */
function emitEvent(eventName, args) {
if (scope.eventhandler) {
@@ -66,6 +72,8 @@ angular.module("umbraco.directives")
}
}
/*this is the only external interface a tree has */
function setupExternalEvents() {
if (scope.eventhandler) {
@@ -78,29 +86,71 @@ angular.module("umbraco.directives")
loadTree();
};
scope.eventhandler.reloadNode = function(node){
scope.loadChildren(node, true);
};
scope.eventhandler.syncPath = function(path, forceReload){
if(!angular.isArray(path)){
path = path.split(',');
if(angular.isString(path)){
path = path.replace('"', '').split(',');
}
//reset current node selection
scope.currentNode = undefined;
//filter the path for root node ids
path = _.filter(path, function(item){ return (item !== "init" && item !== "-1"); });
//if we have a active tree, we sync based on that.
var root = activeTree ? activeTree : scope.tree.root;
//tell the tree to sync the children below the root
syncTree(root, path, forceReload);
loadPath(path, forceReload);
};
scope.eventhandler.setActiveTreeType = function(treeAlias){
activeTree = _.find(scope.tree.root.children, function(node){ return node.metaData.treeAlias === treeAlias; });
loadActiveTree(treeAlias);
};
}
}
//helper to load a specific path on the active tree as soon as its ready
function loadPath(path, forceReload){
function _load(tree, path, forceReload){
syncTree(tree, path, forceReload);
}
if(scope.activeTree){
_load(scope.activeTree, path, forceReload);
}else{
scope.eventhandler.one("activeTreeLoaded", function(e, args){
_load(args.tree, path, forceReload);
});
}
}
//expands the first child with a tree alias as soon as the tree has loaded
function loadActiveTree(treeAlias){
scope.activeTree = undefined;
function _load(tree, alias){
scope.activeTree = _.find(tree.children, function(node){ return node.metaData.treeAlias === treeAlias; });
scope.activeTree.expanded = true;
scope.loadChildren(scope.activeTree, false).then(function(){
emitEvent("activeTreeLoaded", {tree: scope.activeTree});
});
}
if(scope.tree){
_load(scope.tree.root, treeAlias);
}else{
scope.eventhandler.one("treeLoaded", function(e, args){
_load(args.tree, treeAlias);
});
}
}
/** Method to load in the tree data */
function loadTree() {
if (!scope.loading && scope.section) {
@@ -114,15 +164,21 @@ angular.module("umbraco.directives")
.then(function (data) {
//set the data once we have it
scope.tree = data;
//do timeout so that it re-enables them after this digest
$timeout(function() {
//enable delete animations
enableDeleteAnimations = true;
});
},0,false);
scope.loading = false;
//set the root as the current active tree
scope.activeTree = scope.tree.root;
emitEvent("treeLoaded", {tree: scope.tree.root});
}, function (reason) {
scope.loading = false;
notificationsService.error("Tree Error", reason);
@@ -130,31 +186,47 @@ angular.module("umbraco.directives")
}
}
function syncTree(node, array, forceReload) {
if(!node || !array || array.length === 0){
function syncTree(node, path, forceReload) {
if(!node || !path || path.length === 0){
return;
}
scope.loadChildren(node, forceReload)
.then(function(children){
var next = _.where(children, {id: array[0]});
if(next && next.length > 0){
if(array.length > 0){
array.splice(0,1);
}else{
//we are directly above the changed node
var onParent = (path.length === 1);
var needsReload = true;
}
if(array.length === 0){
scope.currentNode = next[0];
}
node.expanded = true;
syncTree(next[0], array, forceReload);
}
});
//if we are not directly above, we will just try to locate
//the node and continue down the path
if(!onParent){
//if we can find the next node in the path
var child = treeService.getChildNode(node, path[0]);
if(child){
needsReload = false;
path.splice(0,1);
syncTree(child, path, forceReload);
}
}
//if a reload is needed, all children will be loaded from server
if(needsReload){
scope.loadChildren(node, forceReload)
.then(function(children){
var child = treeService.getChildNode(node, path[0]);
if(!onParent){
path.splice(0,1);
syncTree(child, path, forceReload);
}else{
scope.currentNode = child;
}
});
}
}
/** method to set the current animation for the node.
* This changes dynamically based on if we are changing sections or just loading normal tree data.
* When changing sections we don't want all of the tree-ndoes to do their 'leave' animations.
@@ -174,8 +246,13 @@ angular.module("umbraco.directives")
//emit treeNodeExpanding event, if a callback object is set on the tree
emitEvent("treeNodeExpanding", {tree: scope.tree, node: node });
if (node.hasChildren && (forceReload || !node.children || (angular.isArray(node.children) && node.children.length === 0))) {
//standardising
if(!node.children){
node.children = [];
}
if (forceReload || (node.hasChildren && node.children.length === 0)) {
//get the children from the tree service
treeService.loadNodeChildren({ node: node, section: scope.section })
.then(function(data) {
@@ -220,6 +297,7 @@ angular.module("umbraco.directives")
emitEvent("treeNodeAltSelect", { element: e, tree: scope.tree, node: n, event: ev });
};
//watch for section changes
scope.$watch("section", function (newVal, oldVal) {