Skip to content

Commit 581bd1d

Browse files
author
Georgii Rychko
authored
Merge pull request #122 from valor-software/tree-api
feature(tree-api): create an API to manipulate a node
2 parents c0f3a2b + 175844e commit 581bd1d

13 files changed

+995
-94
lines changed

README.md

Lines changed: 205 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,19 @@
2323
- [NodeRenamedEvent](#noderenamedevent)
2424
- [NodeExpandedEvent](#nodeexpandedevent)
2525
- [NodeCollapsedEvent](#nodecollapsedevent)
26+
- [:gun: Controller](#gun-controller)
27+
- [select - selecting a node](#select---selecting-a-node)
28+
- [isSelected - checks whether a node is selected](#isselected---checks-whether-a-node-is-selected)
29+
- [collapse - collapses a node](#collapse---collapses-a-node)
30+
- [isCollapsed - check whether a node is collapsed](#iscollapsed---check-whether-a-node-is-collapsed)
31+
- [expand - expands a node](#expand---expands-a-node)
32+
- [isExpanded - checks wheather a node is expanded](#isexpanded---checks-wheather-a-node-is-expanded)
33+
- [rename - renames a node (changes its value underneath)](#rename---renames-a-node-changes-its-value-underneath)
34+
- [remove - removes a node from the tree](#remove---removes-a-node-from-the-tree)
35+
- [addChild - creates a new child node](#addchild---creates-a-new-child-node)
36+
- [changeNodeId - changes node's id](#changenodeid---changes-nodes-id)
37+
- [reloadChildren - load async children once more](#reloadchildren---load-async-children-once-more)
38+
- [setChildren - changes children of a node;](#setchildren---changes-children-of-a-node)
2639
- [SystemJS](#systemjs)
2740
- [Changes that should be taken into account in order to migrate from __ng2-tree V1__ to __ng2-tree V2__](#changes-that-should-be-taken-into-account-in-order-to-migrate-from-__ng2-tree-v1__-to-__ng2-tree-v2__)
2841
- [:bulb: Want to help?](#bulb-want-to-help)
@@ -115,7 +128,7 @@ Voila! That's pretty much it - enjoy :blush:
115128

116129
## :eyes: Demo
117130
Feel free to examine the [demo](https://valor-software.github.io/ng2-tree/index.html) and its [sources](src/demo) to find out how things are wired.
118-
Also there is [another demo built with Angular CLI](https://github.com/rychkog/ng2-tree-demo).
131+
Also, there is [another demo built with Angular CLI](https://github.com/rychkog/ng2-tree-demo).
119132

120133
## :wrench: API
121134

@@ -161,7 +174,7 @@ interface TreeModel {
161174
}
162175
```
163176

164-
As you can see - object that conforms to this interface has a recursive nature, example can be seen below:
177+
As you can see - an object that conforms to this interface has a recursive nature, an example can be seen below:
165178

166179
```typescript
167180
{
@@ -260,7 +273,7 @@ Another worth noting thing is `loadChildren`. This function on `TreeModel` allow
260273
}
261274
```
262275

263-
Node that defines this function is collapsed by default. At the moment of clicking 'Expand' arrow it starts loading its children by calling given function.
276+
Node that defines this function is collapsed by default. At the moment of clicking 'Expand' arrow, it starts loading its children by calling given function.
264277
If `loadChildren` function is given to the node - `children` property is ignored. For more details - have a look at the [Demo](#eyes-demo).
265278

266279
#### Configure node via TreeModelSettings
@@ -309,7 +322,7 @@ Here is an example of its usage:
309322
* `leaf` - String - It specifies a html template which will be included to the left of the leaf's value.
310323
* `leftMenu` - String - It specifies a html template to the right of the node's value. This template becomes clickable and shows a menu on node's click.
311324

312-
All options that's defined on a `parent` are automatically applied to children. If you want you can override them by `settings` of the child node.
325+
All options that are defined on a `parent` are automatically applied to children. If you want you can override them by `settings` of the child node.
313326

314327
### [settings]
315328

@@ -325,7 +338,7 @@ By default `rootIsVisible` equals to `true`
325338

326339
### `Tree` class
327340

328-
Also in the next section you'll be reading about events generated by the `ng2-tree`. And here [Tree](src/tree.ts) class comes in handy for us, because its instances propagated with event objects. Under the hood `ng2-tree` wraps a `TreeModel` provided by the user in `Tree`. And `Tree` in turn has lots of useful methods and properties (like `parent`, `hasChild()`, `isRoot()` etc.)
341+
Also in the next section, you'll be reading about events generated by the `ng2-tree`. And here [Tree](src/tree.ts) class comes in handy for us, because its instances propagated with event objects. Under the hood, `ng2-tree` wraps a `TreeModel` provided by the user in `Tree`. And `Tree` in turn has lots of useful methods and properties (like `parent`, `hasChild()`, `isRoot()` etc.)
329342

330343
### events (nodeMoved, nodeSelected, nodeRenamed, nodeRemoved, nodeCreated, nodeExpanded, nodeCollapsed)
331344

@@ -402,10 +415,10 @@ You can subscribe to `NodeCreatedEvent` by attaching listener to `(nodeCreated)`
402415
</tree>
403416
```
404417

405-
`NodeCreatedEvent` has a `node` property of type `Tree`, which contains a created node.
418+
`NodeCreatedEvent` has a `node` property of type `Tree`, which contains a created node and a `controller` property, which will give you access to node's controller.
406419

407420
```typescript
408-
{node: <Tree>{...}}
421+
{node: <Tree>{...}, controller: <TreeController>{...}}
409422
```
410423

411424
#### NodeRenamedEvent
@@ -421,7 +434,7 @@ You can subscribe to `NodeRenamedEvent` by attaching listener to `(nodeRenamed)`
421434

422435
`NodeRenamedEvent` has three properties:
423436

424-
- `node` contains node that was renamed (instance of `Tree`).
437+
- `node` contains a node that was renamed ( an instance of `Tree`).
425438
- `oldValue` contains a value, that node used to have (it might be `string` or `RenamableNode`)
426439
- `newValue` contains a new value of the node (it might be `string` or `RenamableNode`)
427440

@@ -467,6 +480,188 @@ You can subscribe to `NodeCollapsedEvent` by attaching listener to `(nodeCollaps
467480
{node: <Tree>{...}}
468481
```
469482

483+
## :gun: Controller
484+
First of all you should know how to get a controller of a particular node. You can get a controller of a node only if you set an id property of a node. For example, your tree structure should look like:
485+
486+
```typescript
487+
public tree: TreeModel = {
488+
value: 'Programming languages by programming paradigm',
489+
id: 1,
490+
children: [
491+
{
492+
value: 'Object-oriented programming',
493+
id: 2,
494+
children: [
495+
{value: 'Java', id: 3},
496+
{value: 'C++', id: 4},
497+
{value: 'C#', id 5},
498+
]
499+
},
500+
{
501+
value: 'Prototype-based programming',
502+
id: 6,
503+
children: [
504+
{value: 'JavaScript', id: 7},
505+
{value: 'CoffeeScript', id: 8},
506+
{value: 'Lua', id: 9},
507+
]
508+
}
509+
]
510+
};
511+
```
512+
513+
Ids must be unique within a one tree, otherwise, some controllers will be overwritten and you won't be able to acquire them.
514+
In order to get a node's controller you need to create an Angular local variable out of tree component via hash binding in the template:
515+
516+
```typescript
517+
@Component({
518+
template: '<tree [tree]="tree" #treeComponent></tree>'
519+
})
520+
class TheComponent implements AfterViewInit {
521+
tree: TreeModel = {
522+
value: 'Programming languages by programming paradigm',
523+
id: 1,
524+
children: [
525+
{
526+
value: 'Object-oriented programming',
527+
id: 2,
528+
children: [
529+
{value: 'Java', id: 3},
530+
{value: 'C++', id: 4},
531+
{value: 'C#', id 5},
532+
]
533+
},
534+
{
535+
value: 'Prototype-based programming',
536+
id: 6,
537+
children: [
538+
{value: 'JavaScript', id: 7},
539+
{value: 'CoffeeScript', id: 8},
540+
{value: 'Lua', id: 9},
541+
]
542+
}
543+
]
544+
};
545+
546+
@ViewChild('treeComponent') treeComponent;
547+
548+
ngAfterViewInit(): void {
549+
// ... make use of this.treeComponent ...
550+
}
551+
}
552+
```
553+
554+
then by executing `this.treeComponent.getControllerByNodeId(PUT_HERE_YOUR_NODE_ID)` you'll get an instance of a TreeController (another couple steps and the world is yours =) )
555+
556+
Below are more detailed explanations of the TreeController and its usage. Let's go method by method:
557+
558+
```typescript
559+
const oopNodeController = this.treeComponent.getControllerByNodeId(2);
560+
```
561+
562+
#### select - selects a node
563+
564+
```typescript
565+
oopNodeController.select();
566+
```
567+
568+
This method selects the node and unselects all the other nodes, also it fires a select event.
569+
570+
#### isSelected - checks whether a node is selected
571+
572+
```typescript
573+
oopNodeController.isSelected();
574+
```
575+
576+
This method returns true if the node is selected and false if it isn't.
577+
578+
#### collapse - collapses a node
579+
580+
```typescript
581+
oopNodeController.collapse();
582+
```
583+
584+
This method collapses a node if the node is collapsible (for example we cannot collapse a leaf). If the node gets collapsed successfully - a collapse event gets fired.
585+
586+
#### isCollapsed - check whether a node is collapsed
587+
588+
```typescript
589+
oopNodeController.isCollapsed();
590+
```
591+
592+
This method returns true if the node is collapsed and false otherwise.
593+
594+
#### expand - expands a node
595+
596+
```typescript
597+
oopNodeController.expand();
598+
```
599+
600+
This method expands the node in case it can be expanded. On successful expanding the expand event is fired.
601+
602+
#### isExpanded - checks whether a node is expanded
603+
604+
```typescript
605+
oopNodeController.isExpanded();
606+
```
607+
608+
This method returns true if the node is expanded and false otherwise.
609+
610+
#### rename - renames a node (changes its value underneath)
611+
612+
```typescript
613+
oopNodeController.rename('new value');
614+
```
615+
616+
This method accepts a string and sets it as a node's new value, this action also fires rename event.
617+
618+
#### remove - removes a node from the tree
619+
620+
```typescript
621+
oopNodeController.remove();
622+
```
623+
624+
This method removes the node and its children and fires remove event.
625+
626+
#### addChild - creates a new child node
627+
628+
```typescript
629+
let newNode: TreeModel = {
630+
value: 'Go',
631+
children: []
632+
};
633+
oopNodeController.addChild(newNode);
634+
```
635+
636+
This method accepts a TreeModel and adds it as a child of the parent or as a sibling (depends on which controller this was called - branch controller or a leaf controller).
637+
638+
### changeNodeId - changes node's id
639+
640+
```typescript
641+
oopNodeController.changeNodeId(10);
642+
```
643+
644+
This method can change a node's id. When the user creates a node from node's menu you will access the new node after it's created and this method will provide a way to change the node's id.
645+
646+
### reloadChildren - loads async children once more
647+
648+
```typescript
649+
oopNodeController.reloadChildren();
650+
```
651+
652+
### setChildren - changes children of a node;
653+
654+
```typescript
655+
let newChildren: Array<TreeModel> = [
656+
{value: 'new children 1'},
657+
{value: 'new children 2'},
658+
{value: 'new children 3'}
659+
];
660+
oopNodeController.setChildren(newChildren);
661+
```
662+
663+
This method replaces all existing children of the node with new ones.
664+
470665
## SystemJS
471666
If you are using SystemJS, then you need
472667

@@ -487,10 +682,10 @@ System.config({
487682
- In V1 all events that were inherited from NodeDestructiveEvent used to have property `parent`. It's not the case anymore. If you need a parent you should get it from `node` in event object like `node.parent`;
488683
- All events used to have `node` property of type `TreeModel`. Now `node` is of type [Tree](#tree-class) (as well as `node.parent`);
489684
- `NodeMovedEvent` now has property `previousParent`, which contains tree in which moved node used to be.
490-
- CSS styles in __ng2-tree V2__ are distributed as separate file which you can find in `node_modules/ng2-tree/styles.css`. That allows you to override ng2-tree styles more easely.
685+
- CSS styles in __ng2-tree V2__ are distributed as separate file which you can find in `node_modules/ng2-tree/styles.css`. That allows you to override ng2-tree styles more easily.
491686
492687
## :bulb: Want to help?
493688
494689
I am very appreciate for your ideas, proposals and found bugs which you can put in [github issues](https://github.com/valor-software/ng2-tree/issues). Thanks in advance!
495690
496-
**P.S.** If you find it hard going through documentation, please, let me know which parts of it was difficult to grasp and I will improve them.
691+
**P.S.** If you find it hard going through the documentation, please, let me know which parts of it was difficult to grasp and I will improve them.

0 commit comments

Comments
 (0)