nodeCtx.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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. // 将节点展开至顶层
  61. expandToTop(): void {
  62. let parent = this.parent();
  63. while (parent) {
  64. parent.getCtx().expanded = true;
  65. parent = parent.getCtx().parent();
  66. }
  67. }
  68. parent(): TreeNode<T> | null {
  69. return this.tree.findParent(this.ID());
  70. }
  71. next(): TreeNode<T> | null {
  72. return this.tree.findNext(this.ID());
  73. }
  74. prev(): TreeNode<T> | null {
  75. return this.tree.findPrev(this.ID());
  76. }
  77. // 获取节点子项
  78. children(): TreeNode<T>[] {
  79. return this.tree.parentMap[this.ID()] || [];
  80. }
  81. firstChild(): TreeNode<T> | null {
  82. return this.children()[0] || null;
  83. }
  84. lastChild(): TreeNode<T> | null {
  85. const children = this.children();
  86. return children[children.length - 1] || null;
  87. }
  88. latestChildSeq(): number {
  89. const latestChild = this.lastChild();
  90. if (latestChild) return latestChild.seq;
  91. return 0;
  92. }
  93. // 获取节点后代(包含嵌套子项)
  94. posterity(): TreeNode<T>[] {
  95. const posterity: TreeNode<T>[] = [];
  96. const getChild = (nodes: TreeNode<T>[]): void => {
  97. nodes.forEach(node => {
  98. posterity.push(node);
  99. const children = node.getCtx().children();
  100. if (children.length) {
  101. getChild(children);
  102. }
  103. });
  104. };
  105. getChild(this.children());
  106. return posterity;
  107. }
  108. posterityCount(): number {
  109. return this.posterity().length;
  110. }
  111. // 获取节点的起源节点(根节点,若该节点已为根节点,则返回自身)
  112. progenitor(): TreeNode<T> {
  113. let parent = this.parent();
  114. if (!parent) {
  115. return this.ref;
  116. }
  117. while (parent && parent.getCtx().parent()) {
  118. parent = parent.getCtx().parent() as TreeNode<T>;
  119. }
  120. return parent;
  121. }
  122. // 获取节点所有先代(包含嵌套父项)
  123. ancestor(): TreeNode<T>[] {
  124. const ancestor: TreeNode<T>[] = [];
  125. let parent = this.parent();
  126. while (parent) {
  127. ancestor.push(parent);
  128. parent = parent.getCtx().parent();
  129. }
  130. return ancestor;
  131. }
  132. ancestorCount(): number {
  133. return this.ancestor().length;
  134. }
  135. // 获取同层节点
  136. brothers(includeSelf = true): TreeNode<T>[] {
  137. let nodes = this.tree.parentMap[this.parentID()] || [];
  138. if (!includeSelf) {
  139. nodes = nodes.filter(node => node.ID !== this.ref.ID);
  140. }
  141. return nodes;
  142. }
  143. brothersCount(includeSelf = true): number {
  144. return this.brothers(includeSelf).length;
  145. }
  146. // 获取后兄弟节点们
  147. nextBrothers(): TreeNode<T>[] {
  148. const nodes = this.tree.parentMap[this.parentID()] || [];
  149. return nodes.filter(
  150. node => node.seq >= this.seq() && node.ID !== this.ref.ID
  151. );
  152. }
  153. // 获取前兄弟节点们
  154. prevBrothers(): TreeNode<T>[] {
  155. const nodes = this.tree.parentMap[this.parentID()] || [];
  156. return nodes.filter(
  157. node => node.seq <= this.seq() && node.ID !== this.ref.ID
  158. );
  159. }
  160. // 只有前节点存在才可上移
  161. canUpMove(): boolean {
  162. return !!this.prev();
  163. }
  164. // 只有后节点存在才可下移
  165. canDownMove(): boolean {
  166. return !!this.next();
  167. }
  168. // 只有父节点存在才可升级
  169. canUpLevel(): boolean {
  170. return !!this.parent();
  171. }
  172. // 只有前节点存在才可降级
  173. canDownLevel(): boolean {
  174. return !!this.prev();
  175. }
  176. }