Skip to content

Commit 8a6bb18

Browse files
author
Georgii Rychko
authored
Merge pull request #64 from IndustriaTech/feature/events-collapse-expand
Event listeners - collapse and expand; Id - optional property
2 parents 6cba1cc + c948218 commit 8a6bb18

10 files changed

Lines changed: 319 additions & 24 deletions

README.md

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ ng2-tree is a simple [Angular 2](https://github.com/angular/angular) component f
1313
- [Configure node via TreeModelSettings](#configure-node-via-treemodelsettings)
1414
- [[settings]](#settings)
1515
- [`Tree` class](#tree-class)
16-
- [events (nodeMoved, nodeSelected, nodeRenamed, nodeRemoved, nodeCreated)](#events-nodemoved-nodeselected-noderenamed-noderemoved-nodecreated)
16+
- [events (nodeMoved, nodeSelected, nodeRenamed, nodeRemoved, nodeCreated, nodeExpanded, nodeCollapsed)](#events-nodemoved-nodeselected-noderenamed-noderemoved-nodecreated-nodeexpanded-nodecollapsed)
1717
- [NodeSelectedEvent](#nodeselectedevent)
1818
- [NodeMovedEvent](#nodemovedevent)
1919
- [NodeRemovedEvent](#noderemovedevent)
2020
- [NodeCreatedEvent](#nodecreatedevent)
2121
- [NodeRenamedEvent](#noderenamedevent)
22+
- [NodeExpandedEvent](#nodeexpandedevent)
23+
- [NodeCollapsedEvent](#nodecollapsedevent)
2224
- [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__)
2325
- [:bulb: Want to help?](#bulb-want-to-help)
2426

@@ -124,7 +126,9 @@ Here is the fully stuffed *tree* tag that you can use in your templates:
124126
(nodeRenamed)="handleRenamed($event)"
125127
(nodeSelected)="handleSelected($event)"
126128
(nodeMoved)="handleMoved($event)"
127-
(nodeCreated)="handleCreated($event)">
129+
(nodeCreated)="handleCreated($event)"
130+
(nodeExpanded)="handleExpanded($event)"
131+
(nodeCollapsed)="handleCollapsed($event)">
128132
</tree>
129133
```
130134

@@ -147,6 +151,7 @@ Here is the definition of the `TreeModel` interface:
147151
```typescript
148152
interface TreeModel {
149153
value: string | RenamableNode;
154+
id: string | number;
150155
children?: Array<TreeModel>;
151156
loadChildren?: ChildrenLoadingFunction;
152157
settings?: TreeModelSettings;
@@ -299,7 +304,7 @@ By default `rootIsVisible` equals to `true`
299304

300305
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.)
301306

302-
### events (nodeMoved, nodeSelected, nodeRenamed, nodeRemoved, nodeCreated)
307+
### events (nodeMoved, nodeSelected, nodeRenamed, nodeRemoved, nodeCreated, nodeExpanded, nodeCollapsed)
303308

304309
Here is the diagram that shows tree events' hierarchy
305310

@@ -405,6 +410,40 @@ You can subscribe to `NodeRenamedEvent` by attaching listener to `(nodeRenamed)`
405410
}
406411
```
407412

413+
#### NodeExpandedEvent
414+
415+
You can subscribe to `NodeExpandedEvent` by attaching listener to `(nodeExpanded)` attribute, this event wont fire on initial expansion
416+
417+
```html
418+
<tree
419+
[tree]="tree"
420+
(nodeExpanded)="handleExpanded($event)">
421+
</tree>
422+
```
423+
424+
`NodeExpandedEvent` has a `node` property of type `Tree`, which contains an expanded node.
425+
426+
```typescript
427+
{node: <Tree>{...}}
428+
```
429+
430+
#### NodeCollapsedEvent
431+
432+
You can subscribe to `NodeCollapsedEvent` by attaching listener to `(nodeCollapsed)` attribute
433+
434+
```html
435+
<tree
436+
[tree]="tree"
437+
(nodeCollapsed)="handleCollapsed($event)">
438+
</tree>
439+
```
440+
441+
`NodeCollapsedEvent` has a `node` property of type `Tree`, which contains a collapsed node.
442+
443+
```typescript
444+
{node: <Tree>{...}}
445+
```
446+
408447
## Changes that should be taken into account in order to migrate from __ng2-tree V1__ to __ng2-tree V2__
409448
- Events were reworked:
410449
- 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`;

demo/app.component.ts

Lines changed: 174 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ declare const alertify: any;
1717
(nodeRenamed)="onNodeRenamed($event)"
1818
(nodeSelected)="onNodeSelected($event)"
1919
(nodeMoved)="onNodeMoved($event)"
20-
(nodeCreated)="onNodeCreated($event)">
20+
(nodeCreated)="onNodeCreated($event)"
21+
(nodeExpanded)="onNodeExpanded($event)"
22+
(nodeCollapsed)="onNodeCollapsed($event)">
2123
</tree>
2224
</div>
2325
<div class="tree-container">
@@ -42,9 +44,11 @@ declare const alertify: any;
4244
(nodeRenamed)="onNodeRenamed($event)"
4345
(nodeSelected)="onNodeSelected($event)"
4446
(nodeMoved)="onNodeMoved($event)"
45-
(nodeCreated)="onNodeCreated($event)">
47+
(nodeCreated)="onNodeCreated($event)"
48+
(nodeExpanded)="onNodeExpanded($event)"
49+
(nodeCollapsed)="onNodeCollapsed($event)">
4650
</tree>
47-
</div>
51+
</div>
4852
</div>
4953
`,
5054
styles: [`
@@ -135,18 +139,167 @@ export class AppComponent implements OnInit {
135139

136140
public dfs: TreeModel = {
137141
value: '/',
138-
settings: {
139-
leftMenu: true,
140-
rightMenu: false
141-
},
142+
id: 1,
142143
children: [
143144
{
144-
value: 'bin',
145-
children: [
146-
{value: 'bash'},
147-
{value: 'umount'}
148-
]
149-
}
145+
value: 'bin',
146+
id: 2,
147+
children: [
148+
{value: 'bash', id: 3},
149+
{value: 'umount', id: 4},
150+
{value: 'cp', id: 5},
151+
{value: 'less', id: 6},
152+
{value: 'rmdir', id: 7},
153+
{value: 'touch', id: 8},
154+
{value: 'chgrp', id: 9},
155+
{value: 'chmod', id: 10},
156+
{value: 'chown', id: 11},
157+
{value: 'nano', id: 12}
158+
]
159+
},
160+
{
161+
value: 'boot',
162+
id: 13,
163+
children: [
164+
{
165+
value: 'grub',
166+
id: 14,
167+
children: [
168+
{value: 'fonts', id: 15},
169+
{value: 'gfxblacklist.txt', id: 16},
170+
{value: 'grub.cfg', id: 17},
171+
{value: 'grubenv', id: 18},
172+
{value: 'i386-pc', id: 19},
173+
{value: 'locale', id: 20},
174+
{value: 'unicode.pf2', id: 21}
175+
]
176+
},
177+
{
178+
value: 'lost+found',
179+
id: 22,
180+
children: []
181+
},
182+
{value: 'abi-4.4.0-57-generic', id: 23},
183+
{value: 'config-4.4.0-57-generic', id: 24},
184+
{value: 'initrd.img-4.4.0-47-generic', id: 25},
185+
{value: 'initrd.img-4.4.0-57-generic', id: 26},
186+
{value: 'memtest86+.bin', id: 27},
187+
{value: 'System.map-4.4.0-57-generic', id: 28},
188+
{value: 'memtest86+.elf', id: 29},
189+
{value: 'vmlinuz-4.4.0-57-generic', id: 30},
190+
{value: 'memtest86+_multiboot.bin', id: 31}
191+
]
192+
},
193+
{
194+
value: 'build-no-left-no-right-menus',
195+
id: 32,
196+
settings: {
197+
leftMenu: false,
198+
rightMenu: false
199+
},
200+
children: [
201+
{
202+
value: 'php5-left-menu',
203+
id: 33,
204+
settings: {
205+
leftMenu: true
206+
}
207+
},
208+
{
209+
value: 'grails-left-menu',
210+
id: 335,
211+
settings: {
212+
leftMenu: true
213+
}
214+
},
215+
{
216+
value: 'python-right-menu',
217+
id: 333,
218+
settings: {
219+
rightMenu: true
220+
}
221+
}
222+
]
223+
},
224+
{value: 'cdrom', id: 34, children: []},
225+
{value: 'dev', id: 35, children: []},
226+
{value: 'etc', id: 36, children: []},
227+
{
228+
value: 'home',
229+
id: 37,
230+
children: [
231+
{
232+
value: 'firstUser',
233+
id: 38,
234+
children: [
235+
{
236+
value: 'Documents',
237+
id: 39,
238+
children: [
239+
{
240+
value: 'home',
241+
id: 40,
242+
children: [
243+
{
244+
value: 'bills',
245+
id: 41,
246+
children: [
247+
{value: '2016-07-01-mobile.pdf', id: 42},
248+
{value: '2016-07-01-electricity.pdf', id: 43},
249+
{value: '2016-07-01-water.pdf', id: 44},
250+
{value: '2016-07-01-internet.pdf', id: 45},
251+
{value: '2016-08-01-mobile.pdf', id: 46},
252+
{value: '2016-10-01-internet.pdf', id: 47}
253+
]
254+
},
255+
{value: 'photos', id: 48, children: []}
256+
]
257+
}
258+
]
259+
},
260+
{value: 'Downloads', id: 49, children: []},
261+
{value: 'Desktop', id: 50, children: []},
262+
{value: 'Pictures', id: 51, children: []},
263+
{value: 'Music', id: 52, children: []},
264+
{value: 'Public', id: 53, children: []}
265+
]
266+
},
267+
{
268+
value: 'secondUser',
269+
id: 54,
270+
children: [
271+
{value: 'Documents', id: 55, children: []},
272+
{
273+
value: 'Downloads',
274+
id: 56,
275+
children: [
276+
{value: 'Actobat3', id: 57},
277+
{value: 'Complib', id: 58},
278+
{value: 'Eudora', id: 59},
279+
{value: 'java', id: 60},
280+
{value: 'drivers', id: 61},
281+
{value: 'kathy', id: 62}
282+
]
283+
},
284+
{value: 'Desktop', id: 63, children: []},
285+
{value: 'Pictures', id: 64, children: []},
286+
{value: 'Music', id: 65, children: []},
287+
{value: 'Public', id: 66, children: []}
288+
]
289+
}
290+
]
291+
},
292+
{value: 'lib', id: 67, children: [] },
293+
{value: 'media', id: 68, children: [] },
294+
{value: 'opt', id: 69, children: [] },
295+
{value: 'proc', id: 70, children: [] },
296+
{value: 'root', id: 71, children: [] },
297+
{value: 'run', id: 72, children: [] },
298+
{value: 'sbin', id: 73, children: [] },
299+
{value: 'srv', id: 74, children: [] },
300+
{value: 'sys', id: 75, children: [] },
301+
{value: 'usr', id: 76, children: [] },
302+
{value: 'var', id: 77, children: [] }
150303
]
151304
};
152305

@@ -213,6 +366,14 @@ export class AppComponent implements OnInit {
213366
AppComponent.logEvent(e, 'Selected');
214367
}
215368

369+
public onNodeExpanded(e: NodeEvent): void {
370+
AppComponent.logEvent(e, 'Expanded');
371+
}
372+
373+
public onNodeCollapsed(e: NodeEvent): void {
374+
AppComponent.logEvent(e, 'Collapsed');
375+
}
376+
216377
private static logEvent(e: NodeEvent, message: string): void {
217378
console.log(e);
218379
alertify.message(`${message}: ${e.node.value}`);

index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import {
1616
NodeRenamedEvent,
1717
NodeMovedEvent,
1818
NodeSelectedEvent,
19+
NodeExpandedEvent,
20+
NodeCollapsedEvent,
1921
NodeDestructiveEvent
2022
} from './src/tree.events';
2123

@@ -35,6 +37,8 @@ export {
3537
NodeRenamedEvent,
3638
NodeMovedEvent,
3739
NodeSelectedEvent,
40+
NodeExpandedEvent,
41+
NodeCollapsedEvent,
3842
NodeDestructiveEvent,
3943
TreeComponent,
4044
TreeModule

src/tree-internal.component.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { Observable } from 'rxjs';
2020
[nodeDraggable]="element"
2121
[tree]="tree">
2222
23-
<div class="folding" (click)="tree.switchFoldingType()" [ngClass]="tree.foldingType.cssClass"></div>
23+
<div class="folding" (click)="onSwitchFoldingType()" [ngClass]="tree.foldingType.cssClass"></div>
2424
<div class="node-value"
2525
*ngIf="!shouldShowInputForTreeValue()"
2626
[class.node-selected]="isSelected"
@@ -62,7 +62,7 @@ export class TreeInternalComponent implements OnInit {
6262
public isLeftMenuVisible: boolean = false;
6363

6464
public constructor(@Inject(NodeMenuService) private nodeMenuService: NodeMenuService,
65-
@Inject(TreeService) private treeService: TreeService,
65+
@Inject(TreeService) public treeService: TreeService,
6666
@Inject(ElementRef) public element: ElementRef) {
6767
}
6868

@@ -175,6 +175,11 @@ export class TreeInternalComponent implements OnInit {
175175
this.treeService.fireNodeRemoved(this.tree);
176176
}
177177

178+
private onSwitchFoldingType(): void {
179+
this.tree.switchFoldingType();
180+
this.treeService.fireNodeSwitchFoldingType(this.tree);
181+
}
182+
178183
public applyNewValue(e: NodeEditableEvent): void {
179184
if ((e.action === NodeEditableEventAction.Cancel || this.tree.isNew()) && Tree.isValueEmpty(e.value)) {
180185
return this.treeService.fireNodeRemoved(this.tree);

src/tree.component.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ export class TreeComponent implements OnInit, OnChanges {
3535
@Output()
3636
public nodeMoved: EventEmitter<any> = new EventEmitter();
3737

38+
@Output()
39+
public nodeExpanded: EventEmitter<any> = new EventEmitter();
40+
41+
@Output()
42+
public nodeCollapsed: EventEmitter<any> = new EventEmitter();
43+
3844
public tree: Tree;
3945

4046
public constructor(@Inject(TreeService) private treeService: TreeService) {
@@ -68,5 +74,13 @@ export class TreeComponent implements OnInit, OnChanges {
6874
this.treeService.nodeMoved$.subscribe((e: NodeEvent) => {
6975
this.nodeMoved.emit(e);
7076
});
77+
78+
this.treeService.nodeExpanded$.subscribe((e: NodeEvent) => {
79+
this.nodeExpanded.emit(e);
80+
});
81+
82+
this.treeService.nodeCollapsed$.subscribe((e: NodeEvent) => {
83+
this.nodeCollapsed.emit(e);
84+
});
7185
}
7286
}

src/tree.events.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,15 @@ export class NodeRenamedEvent extends NodeDestructiveEvent {
4141
super(node);
4242
}
4343
}
44+
45+
export class NodeExpandedEvent extends NodeEvent {
46+
public constructor(node: Tree) {
47+
super(node);
48+
}
49+
}
50+
51+
export class NodeCollapsedEvent extends NodeEvent {
52+
public constructor(node: Tree) {
53+
super(node);
54+
}
55+
}

0 commit comments

Comments
 (0)