From fbc83f10d08a54dc9e8a8e316748e4f8fca5dcec Mon Sep 17 00:00:00 2001 From: BccSafe Date: Fri, 5 Feb 2016 22:56:33 +0800 Subject: [PATCH 1/2] server-side processing data support --- angular-tree-control.js | 57 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 6 deletions(-) mode change 100644 => 100755 angular-tree-control.js diff --git a/angular-tree-control.js b/angular-tree-control.js old mode 100644 new mode 100755 index df0845d..2f61db6 --- a/angular-tree-control.js +++ b/angular-tree-control.js @@ -4,7 +4,9 @@ if (typeof module !== "undefined" && typeof exports !== "undefined" && module.ex } (function ( angular ) { 'use strict'; - + + var place_holder_symbol = "place_holder_symbol"; + angular.module( 'treeControl', [] ) .constant('treeConfig', { templateUrl: null @@ -41,6 +43,7 @@ if (typeof module !== "undefined" && typeof exports !== "undefined" && module.ex expandedNodes: "=?", onSelection: "&", onNodeToggle: "&", + onNodeRequestData: '&', options: "=?", orderBy: "@", reverseOrder: "@", @@ -86,6 +89,18 @@ if (typeof module !== "undefined" && typeof exports !== "undefined" && module.ex return true; } + function isPlaceHolderSymbol(node) { + return node.placeHolderSymbol == place_holder_symbol; + } + + function isNeedExpandRequestData(node) { + return (angular.isArray(node[$scope.options.nodeChildren]) && node[$scope.options.nodeChildren].length == 1 && isPlaceHolderSymbol(node[$scope.options.nodeChildren][0])); + } + + $scope.getParentNode = function(transcludedScope) { + return (transcludedScope.$parent.node === transcludedScope.synteticRoot)?null:transcludedScope.$parent.node; + }; + $scope.options = $scope.options || {}; ensureDefault($scope.options, "multiSelection", false); ensureDefault($scope.options, "nodeChildren", "children"); @@ -103,7 +118,8 @@ if (typeof module !== "undefined" && typeof exports !== "undefined" && module.ex ensureDefault($scope.options, "isLeaf", defaultIsLeaf); ensureDefault($scope.options, "allowDeselect", true); ensureDefault($scope.options, "isSelectable", defaultIsSelectable); - + ensureDefault($scope.options, "serverSide", false); + $scope.selectedNodes = $scope.selectedNodes || []; $scope.expandedNodes = $scope.expandedNodes || []; $scope.expandedNodesMap = {}; @@ -150,9 +166,7 @@ if (typeof module !== "undefined" && typeof exports !== "undefined" && module.ex return !!$scope.expandedNodesMap[this.$id]; }; - $scope.selectNodeHead = function() { - var transcludedScope = this; - var expanding = $scope.expandedNodesMap[transcludedScope.$id] === undefined; + $scope.toggleNode = function(transcludedScope, expanding) { $scope.expandedNodesMap[transcludedScope.$id] = (expanding ? transcludedScope.node : undefined); if (expanding) { $scope.expandedNodes.push(transcludedScope.node); @@ -168,12 +182,39 @@ if (typeof module !== "undefined" && typeof exports !== "undefined" && module.ex $scope.expandedNodes.splice(index, 1); } if ($scope.onNodeToggle) { - var parentNode = (transcludedScope.$parent.node === transcludedScope.synteticRoot)?null:transcludedScope.$parent.node; + var parentNode = $scope.getParentNode(transcludedScope); $scope.onNodeToggle({node: transcludedScope.node, $parentNode: parentNode, $index: transcludedScope.$index, $first: transcludedScope.$first, $middle: transcludedScope.$middle, $last: transcludedScope.$last, $odd: transcludedScope.$odd, $even: transcludedScope.$even, expanded: expanding}); } + } + + $scope.selectNodeHead = function() { + var transcludedScope = this; + var expanding = $scope.expandedNodesMap[transcludedScope.$id] === undefined; + + if (expanding && $scope.onNodeRequestData && isNeedExpandRequestData(transcludedScope.node)) { + var nodeBuffer = [], + parentNode = $scope.getParentNode(transcludedScope), + promise = $scope.onNodeRequestData({node: nodeBuffer, $parentNode: parentNode, + $index: transcludedScope.$index, $first: transcludedScope.$first, $middle: transcludedScope.$middle, + $last: transcludedScope.$last, $odd: transcludedScope.$odd, $even: transcludedScope.$even, expanded: expanding}); + if ((angular.isObject(promise) || angular.isFunction(promise)) && angular.isFunction(promise.then)){ + promise.then(function() { + if (angular.isArray(nodeBuffer) && nodeBuffer.length > 0) { + transcludedScope.node[$scope.options.nodeChildren] = angular.copy(nodeBuffer); + } else { + transcludedScope.node[$scope.options.nodeChildren] = []; + } + $scope.toggleNode(transcludedScope, expanding); + }); + } else { + throw("the return of on-node-request-data must be a promise"); + } + } else { + $scope.toggleNode(transcludedScope, expanding); + } }; $scope.selectNodeLabel = function( selectedNode){ @@ -285,6 +326,7 @@ if (typeof module !== "undefined" && typeof exports !== "undefined" && module.ex return function ( scope, element, attrs, treemodelCntr ) { scope.$watch("treeModel", function updateNodeOnRootScope(newValue) { + if (angular.isArray(newValue)) { if (angular.isDefined(scope.node) && angular.equals(scope.node[scope.options.nodeChildren], newValue)) return; @@ -351,6 +393,9 @@ if (typeof module !== "undefined" && typeof exports !== "undefined" && module.ex return { restrict: 'A', link: function($scope, $element, $attrs) { + if ($scope.options.serverSide && typeof $scope.node[$scope.options.nodeChildren] == "undefined") { + $scope.node[$scope.options.nodeChildren] = [{placeHolderSymbol: place_holder_symbol}]; + } $element.data('node', $scope.node); $element.data('scope-id', $scope.$id); } From eccc251321b2f47051aa4dab67a32fd2741d6024 Mon Sep 17 00:00:00 2001 From: BccSafe Date: Mon, 15 Feb 2016 10:56:39 +0800 Subject: [PATCH 2/2] improve error hint --- angular-tree-control.js | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/angular-tree-control.js b/angular-tree-control.js index 2f61db6..c28983a 100755 --- a/angular-tree-control.js +++ b/angular-tree-control.js @@ -6,7 +6,7 @@ if (typeof module !== "undefined" && typeof exports !== "undefined" && module.ex 'use strict'; var place_holder_symbol = "place_holder_symbol"; - + angular.module( 'treeControl', [] ) .constant('treeConfig', { templateUrl: null @@ -200,17 +200,21 @@ if (typeof module !== "undefined" && typeof exports !== "undefined" && module.ex promise = $scope.onNodeRequestData({node: nodeBuffer, $parentNode: parentNode, $index: transcludedScope.$index, $first: transcludedScope.$first, $middle: transcludedScope.$middle, $last: transcludedScope.$last, $odd: transcludedScope.$odd, $even: transcludedScope.$even, expanded: expanding}); - if ((angular.isObject(promise) || angular.isFunction(promise)) && angular.isFunction(promise.then)){ - promise.then(function() { - if (angular.isArray(nodeBuffer) && nodeBuffer.length > 0) { - transcludedScope.node[$scope.options.nodeChildren] = angular.copy(nodeBuffer); - } else { - transcludedScope.node[$scope.options.nodeChildren] = []; - } - $scope.toggleNode(transcludedScope, expanding); - }); - } else { - throw("the return of on-node-request-data must be a promise"); + if (promise) { + if ((angular.isObject(promise) || angular.isFunction(promise)) && angular.isFunction(promise.then)){ + promise.then(function() { + if (angular.isArray(nodeBuffer) && nodeBuffer.length > 0) { + transcludedScope.node[$scope.options.nodeChildren] = angular.copy(nodeBuffer); + } else { + transcludedScope.node[$scope.options.nodeChildren] = []; + } + $scope.toggleNode(transcludedScope, expanding); + }); + } else { + throw("the return of on-node-request-data must be a promise"); + } + } else { + throw("on-node-request-data must be defined in serverSide mode"); } } else { $scope.toggleNode(transcludedScope, expanding);