UNPKG

26 kBMarkdownView Raw
1# :herb: ng2-tree
2
3[![npm](https://img.shields.io/npm/v/ng2-tree.svg?style=flat-square)](https://www.npmjs.com/package/ng2-tree)
4[![Travis](https://img.shields.io/travis/valor-software/ng2-tree.svg?style=flat-square)](https://travis-ci.org/valor-software/ng2-tree)
5[![Codecov](https://img.shields.io/codecov/c/github/valor-software/ng2-tree.svg?style=flat-square)](https://codecov.io/github/valor-software/ng2-tree)
6
7<!-- TOC -->
8
9* [:clapper: Usage](#clapper-usage)
10* [:eyes: Demo](#eyes-demo)
11* [:wrench: API](#wrench-api)
12 * [tree](#tree)
13 * [[tree]](#tree)
14 * [Load children asynchronously](#load-children-asynchronously)
15 * [Load children using ngrx (or any redux-like library)](#load-children-using-ngrx-or-any-redux-like-library)
16 * [Configure node via TreeModelSettings](#configure-node-via-treemodelsettings)
17 * [[settings]](#settings)
18 * [`Tree` class](#tree-class)
19 * [events (nodeMoved, nodeSelected, nodeRenamed, nodeRemoved, nodeCreated, nodeExpanded, nodeCollapsed)](#events-nodemoved-nodeselected-noderenamed-noderemoved-nodecreated-nodeexpanded-nodecollapsed)
20 * [NodeSelectedEvent](#nodeselectedevent)
21 * [NodeMovedEvent](#nodemovedevent)
22 * [NodeRemovedEvent](#noderemovedevent)
23 * [NodeCreatedEvent](#nodecreatedevent)
24 * [NodeRenamedEvent](#noderenamedevent)
25 * [NodeExpandedEvent](#nodeexpandedevent)
26 * [NodeCollapsedEvent](#nodecollapsedevent)
27 * [LoadNextLevelEvent](#loadnextlevelevent)
28* [:gun: Controller](#gun-controller)
29 * [select - selects a node](#select---selects-a-node)
30 * [isSelected - checks whether a node is selected](#isselected---checks-whether-a-node-is-selected)
31 * [collapse - collapses a node](#collapse---collapses-a-node)
32 * [isCollapsed - check whether a node is collapsed](#iscollapsed---check-whether-a-node-is-collapsed)
33 * [expand - expands a node](#expand---expands-a-node)
34 * [isExpanded - checks whether a node is expanded](#isexpanded---checks-whether-a-node-is-expanded)
35 * [toTreeModel - converts a tree to a TreeModel instance](#totreemodel---converts-a-tree-to-a-treemodel-instance)
36 * [rename - renames a node (changes its value underneath)](#rename---renames-a-node-changes-its-value-underneath)
37 * [startRenaming - changes the node template so that text input appears and lets a user type a new name](#startrenaming---changes-the-node-template-so-that-text-input-appears-and-lets-a-user-type-a-new-name)
38 * [remove - removes a node from the tree](#remove---removes-a-node-from-the-tree)
39 * [addChild - creates a new child node](#addchild---creates-a-new-child-node)
40 * [changeNodeId - changes node's id](#changenodeid---changes-nodes-id)
41 * [reloadChildren - loads async children once more](#reloadchildren---loads-async-children-once-more)
42 * [setChildren - changes children of a node;](#setchildren---changes-children-of-a-node)
43* [SystemJS](#systemjs)
44* [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__)
45* [:bulb: Want to help?](#bulb-want-to-help)
46
47<!-- /TOC -->
48
49## :clapper: Usage
50
51Ok, let's start with an installation - all you need to do is:
52
53`npm install --save ng2-tree`
54
55Now when you have `ng2-tree` installed, you are in a few steps from having tree in your application:
56
571. Add the `TreeModule` to your application's module `imports` section:
58
59```typescript
60import { NgModule } from '@angular/core';
61import { AppComponent } from './app.component';
62import { BrowserModule } from '@angular/platform-browser';
63import { TreeModule } from 'ng2-tree';
64
65@NgModule({
66 declarations: [MyComponent],
67 imports: [BrowserModule, TreeModule],
68 bootstrap: [MyComponent]
69})
70export class MyModule {}
71```
72
732. As soon as the previous step is done we need to give ng2-tree a model to render - this can be accomplished by populating its `[tree]` attribute with an object that conforms to the `TreeModel` interface (see [API](#wrench-api)):
74
75```typescript
76// 1 - import required classes and interfaces
77import { TreeModel } from 'ng2-tree';
78
79@Component({
80 selector: 'myComp',
81 // 2 - set [tree] attribute to tree object
82 template: `<tree [tree]="tree"></tree>`
83})
84class MyComponent {
85 // 3 - make sure that tree object conforms to the TreeModel interface
86 public tree: TreeModel = {
87 value: 'Programming languages by programming paradigm',
88 children: [
89 {
90 value: 'Object-oriented programming',
91 children: [{ value: 'Java' }, { value: 'C++' }, { value: 'C#' }]
92 },
93 {
94 value: 'Prototype-based programming',
95 children: [{ value: 'JavaScript' }, { value: 'CoffeeScript' }, { value: 'Lua' }]
96 }
97 ]
98 };
99}
100```
101
1023. Apart from that, in order to have usable tree in the browser, you need to add **ng2-tree styles** which you can find in your `node_modules/ng2-tree/styles.css`
103
104In Angular 2/4 cli projects, modify **.angular-cli.json** as below:
105
106```typescript
107 "styles": [
108 "styles.css",
109 "../node_modules/ng2-tree/styles.css"
110 ],
111```
112
1134. And finally, I suppose, you'd want to listen to events generated by ng2-tree (for a full list of supported events look at the [API](#wrench-api)). No problem, this is also easy to do - for example let's add a listener for `node was selected` kind of events:
114
115```typescript
116// 1 - import required classes and interfaces
117import { TreeModel, NodeEvent } from 'ng2-tree';
118
119@Component({
120 selector: 'myComp',
121 // 2 - listent for nodeSelected events and handle them
122 template: `<tree [tree]="tree" (nodeSelected)="logEvent($event)"></tree>`
123})
124class MyComponent {
125 public tree: TreeModel = { ... };
126
127 // 3 - print caught event to the console
128 public logEvent(e: NodeEvent): void {
129 console.log(e);
130 }
131}
132```
133
134Voila! That's pretty much it - enjoy :blush:
135
136## :eyes: Demo
137
138Feel 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.
139Also, there is [another demo built with Angular CLI](https://github.com/rychkog/ng2-tree-demo).
140
141## :wrench: API
142
143Here is the fully stuffed _tree_ tag that you can use in your templates:
144
145```html
146 <tree
147 [tree]="tree"
148 [settings]="settings"
149 (nodeRemoved)="handleRemoved($event)"
150 (nodeRenamed)="handleRenamed($event)"
151 (nodeSelected)="handleSelected($event)"
152 (nodeMoved)="handleMoved($event)"
153 (nodeCreated)="handleCreated($event)"
154 (nodeExpanded)="handleExpanded($event)"
155 (nodeCollapsed)="handleCollapsed($event)"
156 (loadNextLevel)="handleNextLevel($event)">
157 </tree>
158```
159
160Let's go through every element of this structure one by one.
161
162### tree
163
164`tree` is the selector for `TreeComponent` which is bundled into `TreeModule`:
165
166### [tree]
167
168`tree` has a `[tree]` attribute which needs to be populated with an object implementing `TreeModel` interface. You can import this interface like below:
169
170```typescript
171import { TreeModel } from 'ng2-tree';
172```
173
174Here is the definition of the `TreeModel` interface:
175
176```typescript
177interface TreeModel {
178 value: string | RenamableNode;
179 id: string | number;
180 children?: Array<TreeModel>;
181 loadChildren?: ChildrenLoadingFunction;
182 settings?: TreeModelSettings;
183}
184```
185
186As you can see - an object that conforms to this interface has a recursive nature, an example can be seen below:
187
188```typescript
189{
190 value: 'Programming languages by programming paradigm',
191 children: [
192 {
193 value: 'Object-oriented programming',
194 children: [
195 {value: 'Java'},
196 {value: 'C++'},
197 {value: 'C#'}
198 ]
199 },
200 {
201 value: 'Prototype-based programming',
202 children: [
203 {value: 'JavaScript'},
204 {value: 'CoffeeScript'},
205 {value: 'Lua'}
206 ]
207 }
208 ]
209 }
210```
211
212Property `value` can be of type `string` or `RenamableNode`.
213`RenamableNode` gives you an additional control over the way node is renamed and rendered (by rendered I mean its text representation). Here is the definition of the `RenamableNode` interface:
214
215```typescript
216interface RenamableNode {
217 // This method will be invoked in order to apply new value to this kind of node
218 setName(name: string): void;
219
220 // This method will be invoked in order to get a text for rendering as a node value
221 toString(): string;
222}
223```
224
225Here is an example of such a node in the `TreeModel` object:
226
227```typescript
228{
229 value: 'Programming languages by programming paradigm',
230 children: [
231 {
232 value: 'Object-oriented programming',
233 children: [
234 {
235 // I am a RenamableNode. Yeah, that's me :)
236 value: <RenamableNode>{
237 name: 'Java',
238 setName(name: string): void {
239 this.name = name;
240 },
241 toString(): string {
242 return this.name;
243 }
244 }
245 },
246 {value: 'C++'},
247 {value: 'C#'}
248 ]
249 },
250 {
251 value: 'Prototype-based programming',
252 loadChildren: (callback) => {
253 setTimeout(() => {
254 callback([
255 {value: 'JavaScript'},
256 {value: 'CoffeeScript'},
257 {value: 'TypeScript'}
258 ]);
259 }, 5000);
260 }
261 }
262 ]
263 };
264```
265
266#### Load children asynchronously
267
268Another worth noting thing is `loadChildren`. This function on `TreeModel` allows you to load its **children asynchronously**.
269
270```typescript
271{
272 value: 'Prototype-based programming',
273 loadChildren: (callback) => {
274 setTimeout(() => {
275 callback([
276 {value: 'JavaScript'},
277 {value: 'CoffeeScript'},
278 {value: 'TypeScript'}
279 ]);
280 }, 5000);
281 }
282}
283```
284
285Node that defines this function is collapsed by default. At the moment of clicking 'Expand' arrow, it starts loading its children by calling given function.
286If `loadChildren` function is given to the node - `children` property is ignored. For more details - have a look at the [Demo](#eyes-demo).
287
288#### Load children using ngrx (or any redux-like library)
289
290You can also load children by changing the tree state using ngrx.
291The tree can emit an appropriate event notifying you to dispatch a new action in order to load the branch's children.
292
293To enable this feature you should set the `TreeModel.emitLoadNextLevel` property to true:
294
295```typscript
296const model: TreeModel = {
297emitLoadNextLevel : true
298}
299```
300
301Now on the first time the node is expanded a **LoadNextLevelEvent** will be fired (via the **loadNextLevel** EventEmitter in the tree) containing the node that requested a next level (its children) loading.
302
303In your code make sure you change the tree state and add the children to the model.
304
305In addition the regular **NodeExpanded** event will be fired.
306
307**NOTICE**: if both `emitLoadNextLevel` and `loadChildren` are provided, the tree will ignore the `emitLoadNextLevel` and the `LoadNextLevelEvent` won't be fired.
308
309#### Configure node via TreeModelSettings
310
311Apart from that `TreeModel` interface has an optional field called `settings` of type `TreeModelSettings`.
312
313Here is an example of its usage:
314
315```typescript
316{
317 value: 'Prototype-based programming',
318 settings: {
319 'static': true,
320 'rightMenu': true,
321 'leftMenu': true,
322 'cssClasses': {
323 'expanded': 'fa fa-caret-down fa-lg',
324 'collapsed': 'fa fa-caret-right fa-lg',
325 'leaf': 'fa fa-lg',
326 'empty': 'fa fa-caret-right disabled'
327 },
328 'templates': {
329 'node': '<i class="fa fa-folder-o fa-lg"></i>',
330 'leaf': '<i class="fa fa-file-o fa-lg"></i>',
331 'leftMenu': '<i class="fa fa-navicon fa-lg"></i>'
332 },
333 'menuItems': [
334 { action: NodeMenuItemAction.Custom, name: 'Foo', cssClass: 'fa fa-arrow-right' },
335 { action: NodeMenuItemAction.Custom, name: 'Bar', cssClass: 'fa fa-arrow-right' },
336 { action: NodeMenuItemAction.Custom, name: 'Baz', cssClass: 'fa fa-arrow-right'}
337 ]
338 }
339 },
340 children: [
341 {value: 'JavaScript'},
342 {value: 'CoffeeScript'},
343 {value: 'Lua'}
344 ]
345}
346```
347
348* `static` - Boolean - This option makes it impossible to drag a tree or modify it in a some way, though you still can select nodes in the static tree and appropriate events will be generated.
349* `isCollapsedOnInit` - Boolean - This option makes a tree to be collapsed on first load (this option cascades to its children).
350* `rightMenu` - Boolean - This option allows you to activate (true, by default) or deactivate (false) right menu when clicking with right button of a mouse.
351* `leftMenu` - Boolean - This option allows you to activate (true) or deactivate (false, by default) left menu.
352* `cssClasses` - Object:
353 * `expanded` - String - It specifies a css class (or classes) for an item which represents expanded state of a node. The item is clickable and it transitions the node to the collapsed state
354 * `collapsed` - String - It specifies a css class (or classes) for an item which represents collapsed state of a node. The item is clickable and it transitions the node to the expanded state
355 * `leaf` - String - It specifies a css class (or classes) for an item which represents a node without an option to expand or collapse - in other words: a leaf node.
356 * `empty` - String - Node is considered empty when it has no children. Once this condition is satisfied - appropriate css class will be applied to the node.
357* `templates` - Object:
358 * `node` - String - It specifies a html template which will be included to the left of the node's value.
359 * `leaf` - String - It specifies a html template which will be included to the left of the leaf's value.
360 * `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.
361* `menuItems` - here you can specify your custom menu items. You should feed an array of NodeMenuItem instances to this setting. Once done - setup a subscription to `MenuItemSelectedEvent`s by listening to `(menuItemSelected)="onMenuItemSelected($event)"` on the tree.
362
363All 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.
364
365### [settings]
366
367Object that should be passed to `[settings]` must be of type [`Ng2TreeSettings`](src/tree.types.ts). This attribute is **optional**. Right now only one setting is available in there - `rootIsVisible`. This setting allows you to make a root node of the tree _invisible_:
368
369```typescript
370const treeSettings: Ng2TreeSettings = {
371 rootIsVisible: false
372};
373```
374
375By default `rootIsVisible` equals to `true`
376
377### `Tree` class
378
379Also 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.)
380
381### events (nodeMoved, nodeSelected, nodeRenamed, nodeRemoved, nodeCreated, nodeExpanded, nodeCollapsed)
382
383`NodeEvent` is the root of the tree events' hierarchy. It defines property `node` that contains a receiver of the event action (`node` is an instance of the `Tree` class).
384
385`NodeDestructiveEvent` is the parent for all events that cause changes to the structure of the tree or to the node's value.
386
387#### NodeSelectedEvent
388
389You can subscribe to the `NodeSelectedEvent` by attaching listener to the `(nodeSelected)` attribute
390
391```html
392 <tree
393 [tree]="tree"
394 (nodeSelected)="handleSelected($event)">
395 </tree>
396```
397
398`NodeSelectedEvent` has just one property `node` which contains a `Tree` object representing selected node.
399
400```typescript
401{node: <Tree>{...}}
402```
403
404#### NodeMovedEvent
405
406You can subscribe to `NodeMovedEvent` by attaching listener to `(nodeMoved)` attribute
407
408```html
409 <tree
410 [tree]="tree"
411 (nodeMoved)="handleMoved($event)">
412 </tree>
413```
414
415`NodeMovedEvent` has two properties `node` and `previousParent` both of which contain `Tree` objects:
416
417* `node` contains a moved node;
418* `previousParent` contains a previous parent of the moved node;
419
420```typescript
421{node: <Tree>{...}, previousParent: <Tree>{...}}
422```
423
424#### NodeRemovedEvent
425
426You can subscribe to `NodeRemovedEvent` by attaching listener to `(nodeRemoved)` attribute
427
428```html
429 <tree
430 [tree]="tree"
431 (nodeRemoved)="handleRemoved($event)">
432 </tree>
433```
434
435`NodeRemovedEvent` has a `node` property, which contains removed node (of type `Tree`).
436
437```typescript
438{node: <Tree>{...}}
439```
440
441#### NodeCreatedEvent
442
443You can subscribe to `NodeCreatedEvent` by attaching listener to `(nodeCreated)` attribute
444
445```html
446 <tree
447 [tree]="tree"
448 (nodeCreated)="handleCreated($event)">
449 </tree>
450```
451
452`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.
453
454```typescript
455{node: <Tree>{...}}
456```
457
458#### NodeRenamedEvent
459
460You can subscribe to `NodeRenamedEvent` by attaching listener to `(nodeRenamed)` attribute
461
462```html
463 <tree
464 [tree]="tree"
465 (nodeRenamed)="handleRenamed($event)">
466 </tree>
467```
468
469`NodeRenamedEvent` has three properties:
470
471* `node` contains a node that was renamed ( an instance of `Tree`).
472* `oldValue` contains a value, that node used to have (it might be `string` or `RenamableNode`)
473* `newValue` contains a new value of the node (it might be `string` or `RenamableNode`)
474
475```typescript
476{
477 node: <Tree>{...},
478 oldValue: <string|RenamableNode>{...},
479 newValue: <string|RenamableNode>{...}
480}
481```
482
483#### NodeExpandedEvent
484
485You can subscribe to `NodeExpandedEvent` by attaching listener to `(nodeExpanded)` attribute, this event wont fire on initial expansion
486
487```html
488 <tree
489 [tree]="tree"
490 (nodeExpanded)="handleExpanded($event)">
491 </tree>
492```
493
494`NodeExpandedEvent` has a `node` property of type `Tree`, which contains an expanded node.
495
496```typescript
497{node: <Tree>{...}}
498```
499
500#### NodeCollapsedEvent
501
502You can subscribe to `NodeCollapsedEvent` by attaching listener to `(nodeCollapsed)` attribute
503
504```html
505 <tree
506 [tree]="tree"
507 (nodeCollapsed)="handleCollapsed($event)">
508 </tree>
509```
510
511`NodeCollapsedEvent` has a `node` property of type `Tree`, which contains a collapsed node.
512
513```typescript
514{node: <Tree>{...}}
515```
516
517#### LoadNextLevelEvent
518
519You can subscribe to `LoadNextLevelEvent` by attaching a listener to `(loadNextLevel)` attribute.
520Relevant for loading children via ngrx (or any redux-inspired library).
521
522```html
523 <tree
524 [tree]="tree"
525 (loadNextLevel)="handleNextLevel($event)">
526 </tree>
527```
528
529`LoadNextLevelEvent` has a `node` property of the type `Tree`, which contains a node for which next level (its children) should be loaded.
530
531```typescript
532{node: <Tree>{...}}
533```
534
535## :gun: Controller
536
537First 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.
538
539> TIP: Ids for nodes created via the context menu or using a TreeController instance get populated automatically unless nodes had ids before there were added to the tree
540
541For example, your tree structure should look like:
542
543```typescript
544public tree: TreeModel = {
545 value: 'Programming languages by programming paradigm',
546 id: 1,
547 children: [
548 {
549 value: 'Object-oriented programming',
550 id: 2,
551 children: [
552 {value: 'Java', id: 3},
553 {value: 'C++', id: 4},
554 {value: 'C#', id 5},
555 ]
556 },
557 {
558 value: 'Prototype-based programming',
559 id: 6,
560 children: [
561 {value: 'JavaScript', id: 7},
562 {value: 'CoffeeScript', id: 8},
563 {value: 'Lua', id: 9},
564 ]
565 }
566 ]
567 };
568```
569
570Ids must be unique within a one tree, otherwise, some controllers will be overwritten and you won't be able to acquire them.
571In 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:
572
573```typescript
574@Component({
575 template: '<tree [tree]="tree" #treeComponent></tree>'
576})
577class TheComponent implements AfterViewInit {
578 tree: TreeModel = {
579 value: 'Programming languages by programming paradigm',
580 id: 1,
581 children: [
582 {
583 value: 'Object-oriented programming',
584 id: 2,
585 children: [
586 {value: 'Java', id: 3},
587 {value: 'C++', id: 4},
588 {value: 'C#', id 5},
589 ]
590 },
591 {
592 value: 'Prototype-based programming',
593 id: 6,
594 children: [
595 {value: 'JavaScript', id: 7},
596 {value: 'CoffeeScript', id: 8},
597 {value: 'Lua', id: 9},
598 ]
599 }
600 ]
601 };
602
603 @ViewChild('treeComponent') treeComponent;
604
605 ngAfterViewInit(): void {
606 // ... make use of this.treeComponent ...
607 }
608}
609```
610
611then 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 =) )
612
613Below are more detailed explanations of the TreeController and its usage. Let's go method by method:
614
615```typescript
616const oopNodeController = this.treeComponent.getControllerByNodeId(2);
617```
618
619#### select - selects a node
620
621```typescript
622oopNodeController.select();
623```
624
625This method selects the node and unselects all the other nodes, also it fires a select event.
626
627#### isSelected - checks whether a node is selected
628
629```typescript
630oopNodeController.isSelected();
631```
632
633This method returns true if the node is selected and false if it isn't.
634
635#### collapse - collapses a node
636
637```typescript
638oopNodeController.collapse();
639```
640
641This 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.
642
643#### isCollapsed - check whether a node is collapsed
644
645```typescript
646oopNodeController.isCollapsed();
647```
648
649This method returns true if the node is collapsed and false otherwise.
650
651#### expand - expands a node
652
653```typescript
654oopNodeController.expand();
655```
656
657This method expands the node in case it can be expanded. On successful expanding the expand event is fired.
658
659#### expandToParent - expands a node and its parents up to the root
660
661```typescript
662oopNodeController.expandToParent();
663```
664
665This method expands the node even if it is a leaf. Expand event is fired for every expanded parent up to the root.
666
667**Important:** For this to work - `keepNodesInDOM: true` should be set on the appropriate tree.
668
669#### isExpanded - checks whether a node is expanded
670
671```typescript
672oopNodeController.isExpanded();
673```
674
675#### toTreeModel - converts a tree to a TreeModel instance
676
677Actually controller makes and returns a clone of tree's underlying model
678
679```typescript
680oopNodeController.toTreeModel();
681```
682
683This method returns true if the node is expanded and false otherwise.
684
685#### rename - renames a node (changes its value underneath)
686
687```typescript
688oopNodeController.rename('new value');
689```
690
691This method accepts a string and sets it as a node's new value, this action also fires rename event.
692
693#### startRenaming - changes the node template so that text input appears and lets a user type a new name
694
695```typescript
696oopNodeController.startRenaming();
697```
698
699After the user entered the new name a rename event will be fired.
700
701#### remove - removes a node from the tree
702
703```typescript
704oopNodeController.remove();
705```
706
707This method removes the node and its children and fires remove event.
708
709#### addChild - creates a new child node
710
711```typescript
712let newNode: TreeModel = {
713 value: 'Go',
714 children: []
715};
716oopNodeController.addChild(newNode);
717```
718
719This 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).
720
721### changeNodeId - changes node's id
722
723```typescript
724oopNodeController.changeNodeId(10);
725```
726
727This 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.
728
729### reloadChildren - loads async children once more
730
731```typescript
732oopNodeController.reloadChildren();
733```
734
735### setChildren - changes children of a node;
736
737```typescript
738let newChildren: Array<TreeModel> = [
739 { value: 'new children 1' },
740 { value: 'new children 2' },
741 { value: 'new children 3' }
742];
743oopNodeController.setChildren(newChildren);
744```
745
746This method replaces all existing children of the node with new ones.
747
748## SystemJS
749
750If you are using SystemJS, then you need
751
752```javascript
753System.config({
754 // ...
755 map: {
756 // ...
757 'ng2-tree': 'node_modules/ng2-tree/bundles/ng2-tree.umd.min.js',
758 // ...
759 },
760 // ...
761}
762```
763
764## Changes that should be taken into account in order to migrate from **ng2-tree V1** to **ng2-tree V2**
765
766* Events were reworked:
767 * 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`;
768 * All events used to have `node` property of type `TreeModel`. Now `node` is of type [Tree](#tree-class) (as well as `node.parent`);
769 * `NodeMovedEvent` now has property `previousParent`, which contains tree in which moved node used to be.
770* 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.
771
772## :bulb: Want to help?
773
774I 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!
775
776**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.