nodeCtx.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. import { TreeRaw, TreeNode, Tree } from './tree';
  2. export class NodeContext<T extends TreeRaw = TreeRaw> {
  3. // 对树节点数据的引用
  4. ref: TreeNode<T>;
  5. tree: Tree<T>;
  6. // 展开收起
  7. expanded = false;
  8. constructor(node: TreeNode<T>, tree: Tree<T>, expanded?: boolean) {
  9. this.ref = node;
  10. this.tree = tree;
  11. if (expanded) {
  12. this.expanded = expanded;
  13. }
  14. }
  15. ID(): string {
  16. return this.ref.ID;
  17. }
  18. parentID(): string {
  19. return this.ref.parentID;
  20. }
  21. // 节点在完整、排好序的树数据中的行号
  22. row(): number {
  23. return this.tree.data.findIndex(item => item.ID === this.ref.ID);
  24. }
  25. // 获取树结构展开显示的行号
  26. visualRow(): number {
  27. let row = 0;
  28. for (const n of this.tree.data) {
  29. if (this.ref.ID === n.ID) return row;
  30. if (n.getCtx().visible()) {
  31. row += 1;
  32. }
  33. }
  34. return row;
  35. }
  36. // 节点在相同父节点下的行号
  37. rowInParent(): number {
  38. return this.brothers().findIndex(item => item.ID === this.ref.ID);
  39. }
  40. // 节点的原始seq数据
  41. seq(): number {
  42. return this.ref.seq;
  43. }
  44. // 节点深度,根节点深度为0
  45. depth(): number {
  46. const parent = this.parent();
  47. return parent ? parent.getCtx().depth() + 1 : 0;
  48. }
  49. // 节点是否可见,根据先代节点的expanded就可以计算出来,不需要维护visible属性
  50. visible(): boolean {
  51. let parent = this.parent();
  52. while (parent) {
  53. if (!parent.getCtx().expanded) {
  54. return false;
  55. }
  56. parent = parent.getCtx().parent();
  57. }
  58. return true;
  59. }
  60. parent(): TreeNode<T> | null {
  61. return this.tree.findParent(this.ID());
  62. }
  63. next(): TreeNode<T> | null {
  64. return this.tree.findNext(this.ID());
  65. }
  66. prev(): TreeNode<T> | null {
  67. return this.tree.findPrev(this.ID());
  68. }
  69. // 获取节点子项
  70. children(): TreeNode<T>[] {
  71. return this.tree.parentMap[this.ID()] || [];
  72. }
  73. firstChild(): TreeNode<T> | null {
  74. return this.children()[0] || null;
  75. }
  76. lastChild(): TreeNode<T> | null {
  77. const children = this.children();
  78. return children[children.length - 1] || null;
  79. }
  80. latestChildSeq(): number {
  81. const latestChild = this.lastChild();
  82. if (latestChild) return latestChild.seq;
  83. return 0;
  84. }
  85. // 获取节点后代(包含嵌套子项)
  86. posterity(): TreeNode<T>[] {
  87. const posterity: TreeNode<T>[] = [];
  88. const getChild = (nodes: TreeNode<T>[]): void => {
  89. nodes.forEach(node => {
  90. posterity.push(node);
  91. const children = node.getCtx().children();
  92. if (children.length) {
  93. getChild(children);
  94. }
  95. });
  96. };
  97. getChild(this.children());
  98. return posterity;
  99. }
  100. posterityCount(): number {
  101. return this.posterity().length;
  102. }
  103. // 获取节点的起源节点(根节点,若该节点已为根节点,则返回自身)
  104. progenitor(): TreeNode<T> {
  105. let parent = this.parent();
  106. if (!parent) {
  107. return this.ref;
  108. }
  109. while (parent && parent.getCtx().parent()) {
  110. parent = parent.getCtx().parent() as TreeNode<T>;
  111. }
  112. return parent;
  113. }
  114. // 获取节点所有先代(包含嵌套父项)
  115. ancestor(): TreeNode<T>[] {
  116. const ancestor: TreeNode<T>[] = [];
  117. let parent = this.parent();
  118. while (parent) {
  119. ancestor.push(parent);
  120. parent = parent.getCtx().parent();
  121. }
  122. return ancestor;
  123. }
  124. ancestorCount(): number {
  125. return this.ancestor().length;
  126. }
  127. // 获取同层节点
  128. brothers(includeSelf = true): TreeNode<T>[] {
  129. let nodes = this.tree.parentMap[this.parentID()] || [];
  130. if (!includeSelf) {
  131. nodes = nodes.filter(node => node.ID !== this.ref.ID);
  132. }
  133. return nodes;
  134. }
  135. brothersCount(includeSelf = true): number {
  136. return this.brothers(includeSelf).length;
  137. }
  138. // 获取后兄弟节点们
  139. nextBrothers(): TreeNode<T>[] {
  140. const nodes = this.tree.parentMap[this.parentID()] || [];
  141. return nodes.filter(
  142. node => node.seq >= this.seq() && node.ID !== this.ref.ID
  143. );
  144. }
  145. // 获取前兄弟节点们
  146. prevBrothers(): TreeNode<T>[] {
  147. const nodes = this.tree.parentMap[this.parentID()] || [];
  148. return nodes.filter(
  149. node => node.seq <= this.seq() && node.ID !== this.ref.ID
  150. );
  151. }
  152. // 只有前节点存在才可上移
  153. canUpMove(): boolean {
  154. return !!this.prev();
  155. }
  156. // 只有后节点存在才可下移
  157. canDownMove(): boolean {
  158. return !!this.next();
  159. }
  160. // 只有父节点存在才可升级
  161. canUpLevel(): boolean {
  162. return !!this.parent();
  163. }
  164. // 只有前节点存在才可降级
  165. canDownLevel(): boolean {
  166. return !!this.prev();
  167. }
  168. }