path_tree.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. const createNewPathTree = function (setting) {
  2. const treeSetting = JSON.parse(JSON.stringify(setting));
  3. const itemsPre = 'id_';
  4. const postData = function (url, data, successCallback) {
  5. $.ajax({
  6. type:"POST",
  7. url: url,
  8. data: {'data': JSON.stringify(data)},
  9. dataType: 'json',
  10. cache: false,
  11. timeout: 5000,
  12. beforeSend: function(xhr) {
  13. let csrfToken = Cookies.get('csrfToken');
  14. xhr.setRequestHeader('x-csrf-token', csrfToken);
  15. },
  16. success: function(result){
  17. if (result.err === 0) {
  18. if (successCallback) {
  19. successCallback(result.data);
  20. }
  21. } else {
  22. toast('error: ' + result.message, 'error', 'exclamation-circle');
  23. }
  24. },
  25. error: function(jqXHR, textStatus, errorThrown){
  26. toast('error ' + textStatus + " " + errorThrown, 'error', 'exclamation-circle');
  27. }
  28. });
  29. };
  30. const PathTree = function () {
  31. // 无索引
  32. this.datas = [];
  33. // 以key为索引
  34. this.items = {};
  35. // 以排序为索引
  36. this.nodes = [];
  37. };
  38. const proto = PathTree.prototype;
  39. /**
  40. * 树结构根据显示排序
  41. */
  42. proto.sortTreeNode = function () {
  43. const self = this;
  44. const addSortNodes = function (nodes) {
  45. for (let i = 0; i < nodes.length; i++) {
  46. self.nodes.push(nodes[i]);
  47. addSortNodes(self.getChildren(nodes[i]));
  48. }
  49. };
  50. self.nodes = [];
  51. addSortNodes(this.getChildren(null));
  52. };
  53. /**
  54. * 加载数据(初始化), 并给数据添加部分树结构必须数据
  55. * @param datas
  56. */
  57. proto.loadDatas = function (datas) {
  58. // 清空旧数据
  59. this.items = {};
  60. this.nodes = [];
  61. // 加载全部数据
  62. for (const data of datas) {
  63. const keyName = itemsPre + data[treeSetting.id];
  64. this.items[keyName] = JSON.parse(JSON.stringify(data));
  65. this.datas.push(this.items[keyName]);
  66. }
  67. this.sortTreeNode();
  68. for (const node of this.nodes) {
  69. const children = this.getChildren(node);
  70. node.expanded = children.length > 0;
  71. }
  72. };
  73. /**
  74. * 加载数据(动态),只加载不同部分
  75. * @param {Array} datas
  76. * @privateA
  77. */
  78. proto._loadData = function (datas) {
  79. for (const data of datas) {
  80. let node = this.getItems(data[treeSetting]);
  81. if (node) {
  82. for (const prop of node.propertyNameList) {
  83. if (data[prop]) {
  84. node[prop] = data[prop];
  85. }
  86. }
  87. } else {
  88. const keyName = itemsPre + data[treeSetting.id];
  89. this.items[keyName] = JSON.parse(JSON.stringify(data));
  90. this.datas.push(this.items[keyName]);
  91. }
  92. }
  93. this.sortTreeNode();
  94. }
  95. /**
  96. * 根据id获取树结构节点数据
  97. * @param {Number} id
  98. * @returns {Object}
  99. */
  100. proto.getItems = function (id) {
  101. return this.items[itemsPre + id];
  102. };
  103. /**
  104. * 查找node的parent
  105. * @param {Object} node
  106. * @returns {Object}
  107. */
  108. proto.getParent = function (node) {
  109. return this.getItems(node[treeSetting.pid]);
  110. };
  111. /**
  112. * 查询node的已下载子节点
  113. * @param {Object} node
  114. * @returns {Array}
  115. */
  116. proto.getChildren = function (node) {
  117. const pid = node ? node[treeSetting.id] : treeSetting.rootId;
  118. const children = this.datas.filter(function (x) {
  119. return x[treeSetting.pid] === pid;
  120. });
  121. children.sort(function (a, b) {
  122. return a.order - b.order;
  123. });
  124. return children;
  125. };
  126. /**
  127. * 查询node的已下载的全部后代
  128. * @param {Object} node
  129. * @returns {Array}
  130. */
  131. proto.getPosterity = function (node) {
  132. const reg = new RegExp('^' + node.full_path);
  133. return this.datas.filter(function (x) {
  134. return reg.check(x.full_path);
  135. })
  136. };
  137. /**
  138. * 查询node是否是父节点的最后一个子节点
  139. * @param {Object} node
  140. * @returns {boolean}
  141. */
  142. proto.isLastSibling = function (node) {
  143. const siblings = this.getChildren(this.getParent(node));
  144. return node.order === siblings.length;
  145. };
  146. /**
  147. * 以下方法需等待响应
  148. */
  149. /**
  150. * 加载子节点, callback中应刷新界面
  151. * @param {Object} node
  152. * @param {function} callback
  153. */
  154. proto.loadChildren = function (node, callback) {
  155. const self = this;
  156. postData('get-children', {id: node[treeSetting.id]}, function (data) {
  157. self._loadData(data);
  158. callback();
  159. });
  160. }
  161. return new PathTree();
  162. }