Fixes initial tree load and tree sync, the cachekey was not being used on init which causes the tree to double load which causes all sorts of odd things to happen

This commit is contained in:
Shannon
2018-06-20 21:01:54 +10:00
parent 6bc1ed588b
commit d6e7be1b0b
4 changed files with 85 additions and 106 deletions

View File

@@ -63,7 +63,7 @@ function umbTreeDirective($q, $rootScope, treeService, notificationsService, use
vm.emitEvent = emitEvent;
vm.load = load;
vm.reloadNode = reloadNode;
vm.syncTree = syncTree;
vm.syncTree = syncTree;
vm.loadChildren = loadChildren;
//wire up the exposed api object for hosting controllers
@@ -155,46 +155,21 @@ function umbTreeDirective($q, $rootScope, treeService, notificationsService, use
args.path = _.filter(args.path, function (item) { return (item !== "init" && item !== "-1"); });
//Once those are filtered we need to check if the current user has a special start node id,
// if they do, then we're going to trim the start of the array for anything found from that start node
// and previous so that the tree syncs properly. The tree syncs from the top down and if there are parts
// of the tree's path in there that don't actually exist in the dom/model then syncing will not work.
var treeNode = loadActiveTree(args.tree);
return userService.getCurrentUser().then(function (userData) {
return treeService.syncTree({
node: treeNode,
path: args.path,
forceReload: args.forceReload
}).then(function (data) {
var startNodes = [];
for (var i = 0; i < userData.startContentIds; i++) {
startNodes.push(userData.startContentIds[i]);
}
for (var j = 0; j < userData.startMediaIds; j++) {
startNodes.push(userData.startMediaIds[j]);
if (args.activate === undefined || args.activate === true) {
$scope.currentNode = data;
}
_.each(startNodes, function (i) {
var found = _.find(args.path, function (p) {
return String(p) === String(i);
});
if (found) {
args.path = args.path.splice(_.indexOf(args.path, found));
}
});
var treeNode = loadActiveTree(args.tree);
emitEvent("treeSynced", { node: data, activate: args.activate });
return treeService.syncTree({
node: treeNode,
path: args.path,
forceReload: args.forceReload
}).then(function (data) {
if (args.activate === undefined || args.activate === true) {
$scope.currentNode = data;
}
emitEvent("treeSynced", { node: data, activate: args.activate });
return $q.when({ node: data, activate: args.activate });
});
return $q.when({ node: data, activate: args.activate });
});
}
@@ -269,8 +244,8 @@ function umbTreeDirective($q, $rootScope, treeService, notificationsService, use
return $q.reject();
}
}
function loadChildren(node, forceReload) {
function loadChildren(node, forceReload) {
//emit treeNodeExpanding event, if a callback object is set on the tree
emitEvent("treeNodeExpanding", { tree: $scope.tree, node: node });
@@ -295,7 +270,7 @@ function umbTreeDirective($q, $rootScope, treeService, notificationsService, use
return $q.when(node.children);
}
}
}
/** Returns the css classses assigned to the node (div element) */
$scope.getNodeCssClass = function (node) {
@@ -372,6 +347,9 @@ function umbTreeDirective($q, $rootScope, treeService, notificationsService, use
if (args.section) {
$scope.section = args.section;
}
if (args.cacheKey) {
$scope.cachekey = args.cacheKey;
}
}
//load the tree

View File

@@ -29,7 +29,7 @@ angular.module("umbraco.directives")
currentNode: '=',
enablelistviewexpand: '@',
node: '=',
tree: '=' //TODO: Not sure we need this since we are 'require' on the umbTree
tree: '='
},
link: function (scope, element, attrs, umbTreeCtrl) {
@@ -146,9 +146,9 @@ angular.module("umbraco.directives")
};
/* helper to force reloading children of a tree node */
scope.loadChildren = function(node, forceReload) {
scope.loadChildren = function(node, forceReload) {
return umbTreeCtrl.loadChildren(node, forceReload);
};
};
//if the current path contains the node id, we will auto-expand the tree item children
setupNodeDom(scope.node, scope.tree);
@@ -158,44 +158,44 @@ angular.module("umbraco.directives")
if(scope.node.hasChildren && scope.node.metaData.noAccess) {
scope.loadChildren(scope.node);
}
var evts = [];
//listen for section changes
var evts = [];
//listen for section changes
evts.push(eventsService.on("appState.sectionState.changed", function(e, args) {
if (args.key === "currentSection") {
//when the section changes disable all delete animations
//when the section changes disable all delete animations
scope.node.deleteAnimations = false;
}
}));
/** Depending on if any menu is shown and if the menu is shown for the current node, toggle delete animations */
function toggleDeleteAnimations() {
//if both are false then remove animations
var hide = !appState.getMenuState("showMenuDialog") && !appState.getMenuState("showMenu");
if (hide) {
}));
/** Depending on if any menu is shown and if the menu is shown for the current node, toggle delete animations */
function toggleDeleteAnimations() {
//if both are false then remove animations
var hide = !appState.getMenuState("showMenuDialog") && !appState.getMenuState("showMenu");
if (hide) {
scope.node.deleteAnimations = false;
}
else {
//enable animations for this node if it is the node currently showing a context menu
var currentNode = appState.getMenuState("currentNode");
if (currentNode && currentNode.id == scope.node.id) {
}
else {
//enable animations for this node if it is the node currently showing a context menu
var currentNode = appState.getMenuState("currentNode");
if (currentNode && currentNode.id == scope.node.id) {
scope.node.deleteAnimations = true;
}
else {
}
else {
scope.node.deleteAnimations = false;
}
}
}
//listen for context menu and current node changes
evts.push(eventsService.on("appState.menuState.changed", function(e, args) {
if (args.key === "showMenuDialog" || args.key == "showMenu" || args.key == "currentNode") {
}
//listen for context menu and current node changes
evts.push(eventsService.on("appState.menuState.changed", function(e, args) {
if (args.key === "showMenuDialog" || args.key == "showMenu" || args.key == "currentNode") {
toggleDeleteAnimations();
}
}));
//cleanup events
}));
//cleanup events
scope.$on('$destroy', function() {
for (var e in evts) {
eventsService.unsubscribe(evts[e]);

View File

@@ -35,41 +35,41 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS
_getTreeCache: function() {
return treeCache;
},
/** Internal method to track expanded paths on a tree */
_trackExpandedPaths: function (node, expandedPaths) {
if (!node.children || !angular.isArray(node.children) || node.children.length == 0) {
return;
}
//take the last child
var childPath = this.getPath(node.children[node.children.length - 1]).join(",");
//check if this already exists, if so exit
if (expandedPaths.indexOf(childPath) !== -1) {
/** Internal method to track expanded paths on a tree */
_trackExpandedPaths: function (node, expandedPaths) {
if (!node.children || !angular.isArray(node.children) || node.children.length == 0) {
return;
}
if (expandedPaths.length === 0) {
expandedPaths.push(childPath); //track it
}
//take the last child
var childPath = this.getPath(node.children[node.children.length - 1]).join(",");
//check if this already exists, if so exit
if (expandedPaths.indexOf(childPath) !== -1) {
return;
}
var clonedPaths = expandedPaths.slice(0); //make a copy to iterate over so we can modify the original in the iteration
_.each(clonedPaths, function (p) {
if (childPath.startsWith(p + ",")) {
//this means that the node's path supercedes this path stored so we can remove the current 'p' and replace it with node.path
expandedPaths.splice(expandedPaths.indexOf(p), 1); //remove it
}
if (expandedPaths.length === 0) {
expandedPaths.push(childPath); //track it
return;
}
var clonedPaths = expandedPaths.slice(0); //make a copy to iterate over so we can modify the original in the iteration
_.each(clonedPaths, function (p) {
if (childPath.startsWith(p + ",")) {
//this means that the node's path supercedes this path stored so we can remove the current 'p' and replace it with node.path
expandedPaths.splice(expandedPaths.indexOf(p), 1); //remove it
expandedPaths.push(childPath); //replace it
}
else if (p.startsWith(childPath + ",")) {
}
else if (p.startsWith(childPath + ",")) {
//this means we've already tracked a deeper node so we shouldn't track this one
}
else {
}
else {
expandedPaths.push(childPath); //track it
}
});
},
},
/** 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 */
_formatNodeDataForUseInUI: function (parentNode, treeNodes, section, level) {
@@ -85,7 +85,7 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS
parentNode.cssClasses = [];
}
parentNode.cssClasses.push("no-access");
}
}
//create a method outside of the loop to return the parent - otherwise jshint blows up
var funcParent = function() {
@@ -298,12 +298,12 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS
if (args.node.children && args.node.children.length > 0) {
args.node.expanded = true;
args.node.hasChildren = true;
}
//Since we've removed the children & reloaded them, we need to refresh the UI now because the tree node UI doesn't operate on normal angular $watch since that will be pretty slow
}
//Since we've removed the children & reloaded them, we need to refresh the UI now because the tree node UI doesn't operate on normal angular $watch since that will be pretty slow
if (angular.isFunction(args.node.updateNodeData)) {
args.node.updateNodeData(args.node);
}
}
return $q.when(data);
@@ -666,7 +666,7 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS
//set the node loading
node.parent().children[index].loading = false;
//return
//return
return $q.when(node.parent().children[index]);
}
else {
@@ -779,7 +779,7 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS
}
else {
//couldn't find it in the
return self.loadNodeChildren({ node: node, section: node.section }).then(function () {
return self.loadNodeChildren({ node: node, section: node.section }).then(function (children) {
//ok, got the children, let's find it
var found = self.getChildNode(node, args.path[currPathIndex]);
if (found) {
@@ -814,4 +814,4 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS
};
}
angular.module('umbraco.services').factory('treeService', treeService);
angular.module('umbraco.services').factory('treeService', treeService);

View File

@@ -196,7 +196,7 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar
//Listen for section state changes
evts.push(eventsService.on("appState.sectionState.changed", function (e, args) {
//section changed
if (args.key === "currentSection") {
if (args.key === "currentSection" && $scope.currentSection != args.value) {
$scope.currentSection = args.value;
//load the tree
@@ -365,6 +365,7 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar
//because angular doesn't return a promise for the resolve method, we need to resort to some hackery, else
//like normal JS promises we could do resolve(...).then()
onLoaded: function () {
//the nav is ready, let the app know
eventsService.emit("app.navigationReady", { treeApi: $scope.treeApi });
//finally set the section state