Skip to content

Commit 3c2915f

Browse files
committed
feat(node menu): extracted into separate component
1 parent 377230c commit 3c2915f

5 files changed

Lines changed: 95 additions & 67 deletions

File tree

components/ng2-tree-menu.component.ts

Lines changed: 0 additions & 17 deletions
This file was deleted.

components/ng2-tree.component.ts

Lines changed: 33 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import {Input, Component, OnInit} from 'angular2/core';
1+
import {Input, Component, OnInit, EventEmitter, Output} from 'angular2/core';
22
import {CORE_DIRECTIVES} from 'angular2/common';
33
import {Ng2TreeService} from './ng2-tree.service';
4-
import {EditableNodeDirective} from './editable-node.directive.ts';
4+
import {EditableNodeDirective} from './editable-node.directive';
5+
import {NodeMenuComponent} from "./node-menu.component";
6+
import {TreeStatus} from "./types";
57

68
@Component({
79
selector: 'ng2-tree',
@@ -13,18 +15,17 @@ import {EditableNodeDirective} from './editable-node.directive.ts';
1315
<span class="node-value" *ngIf="!edit">{{tree.value}}</span>
1416
<input type="text" class="node-value" editable [nodeValue]="tree.value" (valueChanged)="applyNewValue($event, tree)" *ngIf="edit"/>
1517
</div>
16-
<div class="node-menu" *ngIf="isMenuVisible">
17-
<ul class="node-menu-content">
18-
<li (click)="rename($event, tree)">Rename node</li>
19-
<li (click)="addNode($event, tree)">Add node</li>
20-
<li (click)="remove($event, tree)">Remove node</li>
21-
</ul>
22-
</div>
23-
<ng2-tree *ngFor="#child of tree.children" [tree]="child"></ng2-tree>
18+
19+
<node-menu *ngIf="isMenuVisible"
20+
(removeSelected)="onRemoveSelected()"
21+
(renameSelected)="onRenameSelected()"
22+
(newSelected)="onNewSelected()"></node-menu>
23+
24+
<ng2-tree *ngFor="#child of tree.children" [tree]="child" (nodeRemoved)="onChildRemoved($event)"></ng2-tree>
2425
</li>
2526
</ul>
2627
`,
27-
directives: [EditableNodeDirective, Ng2Tree, CORE_DIRECTIVES]
28+
directives: [EditableNodeDirective, Ng2Tree, NodeMenuComponent, CORE_DIRECTIVES]
2829
})
2930
export class Ng2Tree implements OnInit {
3031
private static COMPONENT_TAG_NAME: string = 'NG2-TREE';
@@ -35,6 +36,9 @@ export class Ng2Tree implements OnInit {
3536
@Input()
3637
private tree: any;
3738

39+
@Output()
40+
private nodeRemoved: EventEmitter<any> = new EventEmitter();
41+
3842
private treeService: Ng2TreeService;
3943
private isMenuVisible: boolean = false;
4044
private edit: boolean = false;
@@ -88,25 +92,28 @@ export class Ng2Tree implements OnInit {
8892
}
8993
}
9094

95+
private onRenameSelected() {
96+
this.edit = true;
97+
}
9198

92-
private addNode($event: any, node: any) {
93-
if ($event.which === 1) {
94-
if (!node.children || !node.children.push) {
95-
node.children = [];
96-
}
97-
node.children.push({value: '', status: 'new'});
98-
}
99+
private onRemoveSelected() {
100+
this.nodeRemoved.emit({node: this.tree});
99101
}
100102

101-
private rename($event: any, node: any) {
102-
if ($event.which === 1) {
103-
this.edit = true;
103+
private onNewSelected() {
104+
if (!this.tree.children || !this.tree.children.push) {
105+
this.tree.children = [];
104106
}
107+
this.tree.children.push({value: '', status: TreeStatus.New});
105108
}
106109

107-
private remove($event: any, node: any) {
108-
if ($event.which === 1) {
109-
this.treeService.emitRemoveEvent({node});
110+
private onChildRemoved(event: any) {
111+
for (let i = 0; i < this.tree.children.length; i++) {
112+
const child = this.tree.children[i];
113+
if (child === event.node) {
114+
this.tree.children.splice(i, 1);
115+
break;
116+
}
110117
}
111118
}
112119

@@ -129,7 +136,7 @@ export class Ng2Tree implements OnInit {
129136
}
130137

131138
if (!$event.value) {
132-
return this.treeService.emitRemoveEvent({node});
139+
return this.nodeRemoved.emit({node: this.tree});
133140
}
134141

135142
this.previousEvent = $event.type;
@@ -140,7 +147,7 @@ export class Ng2Tree implements OnInit {
140147
ngOnInit(): void {
141148
if (!this.tree) return;
142149

143-
if (this.tree.status === 'new') {
150+
if (this.tree.status === TreeStatus.New) {
144151
this.edit = true;
145152
}
146153

@@ -150,18 +157,5 @@ export class Ng2Tree implements OnInit {
150157
this.isMenuVisible = false;
151158
}
152159
});
153-
154-
this.treeService.removeNodeEventStream()
155-
.subscribe(removeEvent => {
156-
if (!this.tree || !this.tree.children) return;
157-
for (let i = 0; i < this.tree.children.length; i++) {
158-
const child = this.tree.children[i];
159-
if (child === removeEvent.node) {
160-
delete this.tree.children[i];
161-
162-
break;
163-
}
164-
}
165-
});
166160
}
167161
}

components/ng2-tree.service.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {Observable} from 'rxjs/Observable';
44
@Injectable()
55
export class Ng2TreeService {
66
private menuEvents$: EventEmitter<any> = new EventEmitter();
7-
private removeEvents$: EventEmitter<any> = new EventEmitter();
87

98
constructor() {
109
window.addEventListener('keyup', (event: any) => {
@@ -13,7 +12,7 @@ export class Ng2TreeService {
1312
}
1413
});
1514

16-
window.addEventListener('click', (event: any) => {
15+
window.addEventListener('click', () => {
1716
this.emitMenuEvent({sender: null, action: 'close'});
1817
});
1918
}
@@ -25,12 +24,4 @@ export class Ng2TreeService {
2524
emitMenuEvent(event: any): void {
2625
this.menuEvents$.emit(event);
2726
}
28-
29-
removeNodeEventStream(): Observable<any> {
30-
return this.removeEvents$;
31-
}
32-
33-
emitRemoveEvent(event: any): void {
34-
this.removeEvents$.emit(event);
35-
}
3627
}

components/node-menu.component.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import {Component, EventEmitter, Output} from "angular2/core";
2+
import {CORE_DIRECTIVES} from "angular2/common";
3+
import {MouseButtons} from "./types";
4+
5+
@Component({
6+
selector: 'node-menu',
7+
directives: [CORE_DIRECTIVES],
8+
template: `
9+
<div class="node-menu">
10+
<ul class="node-menu-content">
11+
<li (click)="onNew($event)">New</li>
12+
<li (click)="onRename($event)">Rename</li>
13+
<li (click)="onRemove($event)">Remove</li>
14+
</ul>
15+
</div>
16+
`
17+
})
18+
export class NodeMenuComponent {
19+
20+
@Output()
21+
private newSelected: EventEmitter<any> = new EventEmitter();
22+
23+
@Output()
24+
private removeSelected: EventEmitter<any> = new EventEmitter();
25+
26+
@Output()
27+
private renameSelected: EventEmitter<any> = new EventEmitter();
28+
29+
private onNew($event: any) {
30+
if (!this.menuItemSelected($event)) {
31+
return;
32+
}
33+
34+
this.newSelected.emit(null);
35+
}
36+
37+
private onRename($event: any) {
38+
if (!this.menuItemSelected($event)) {
39+
return;
40+
}
41+
42+
this.renameSelected.emit(null);
43+
}
44+
45+
private onRemove($event: any) {
46+
if (!this.menuItemSelected($event)) {
47+
return;
48+
}
49+
50+
this.removeSelected.emit(null);
51+
}
52+
53+
private menuItemSelected(event: any) {
54+
return event.which === MouseButtons.Left;
55+
}
56+
}

components/types.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
export interface Tree {
22
value: string;
3-
children: Array<Tree>;
3+
children?: Array<Tree>;
44
status?: TreeStatus
55
}
66

77
export enum TreeStatus {
88
New
99
}
10+
11+
export enum MouseButtons {
12+
Left = 1,
13+
}

0 commit comments

Comments
 (0)