1
1
import {
2
2
Directive ,
3
- HostListener ,
4
3
OnInit ,
5
4
ElementRef ,
6
5
Renderer ,
7
6
Output ,
8
7
EventEmitter ,
9
8
Input ,
10
9
OnDestroy ,
11
- NgZone
10
+ OnChanges ,
11
+ NgZone ,
12
+ SimpleChanges
12
13
} from '@angular/core' ;
13
14
import { Subject } from 'rxjs/Subject' ;
14
15
import { Observable } from 'rxjs/Observable' ;
@@ -35,7 +36,7 @@ const MOVE_CURSOR: string = 'move';
35
36
@Directive ( {
36
37
selector : '[mwlDraggable]'
37
38
} )
38
- export class Draggable implements OnInit , OnDestroy {
39
+ export class Draggable implements OnInit , OnChanges , OnDestroy {
39
40
40
41
@Input ( ) dropData : any ;
41
42
@@ -68,7 +69,13 @@ export class Draggable implements OnInit, OnDestroy {
68
69
*/
69
70
mouseUp : Subject < any > = new Subject ( ) ;
70
71
71
- private mouseMoveEventListenerUnsubscribe : Function ;
72
+ private eventListenerSubscriptions : {
73
+ mousemove ?: Function ,
74
+ mousedown ?: Function ,
75
+ mouseup ?: Function ,
76
+ mouseenter ?: Function ,
77
+ mouseleave ?: Function
78
+ } = { } ;
72
79
73
80
/**
74
81
* @hidden
@@ -82,6 +89,8 @@ export class Draggable implements OnInit, OnDestroy {
82
89
83
90
ngOnInit ( ) : void {
84
91
92
+ this . checkEventListeners ( ) ;
93
+
85
94
const mouseDrag : Observable < any > = this . mouseDown
86
95
. filter ( ( ) => this . canDrag ( ) )
87
96
. flatMap ( ( mouseDownEvent : MouseEvent ) => {
@@ -182,64 +191,75 @@ export class Draggable implements OnInit, OnDestroy {
182
191
183
192
}
184
193
185
- ngOnDestroy ( ) : void {
186
- if ( this . mouseMoveEventListenerUnsubscribe ) {
187
- this . mouseMoveEventListenerUnsubscribe ( ) ;
194
+ ngOnChanges ( changes : SimpleChanges ) : void {
195
+ if ( changes [ 'dragAxis' ] ) {
196
+ this . checkEventListeners ( ) ;
188
197
}
198
+ }
199
+
200
+ ngOnDestroy ( ) : void {
201
+ this . unsubscribeEventListeners ( ) ;
189
202
this . mouseDown . complete ( ) ;
190
203
this . mouseMove . complete ( ) ;
191
204
this . mouseUp . complete ( ) ;
192
205
}
193
206
194
- /**
195
- * @hidden
196
- */
197
- @HostListener ( 'mousedown' , [ '$event' ] )
198
- onMouseDown ( event : MouseEvent ) : void {
199
- this . zone . runOutsideAngular ( ( ) => {
200
- if ( ! this . mouseMoveEventListenerUnsubscribe ) {
201
- this . mouseMoveEventListenerUnsubscribe = this . renderer . listenGlobal ( 'document' , 'mousemove' , ( event : MouseEvent ) => {
202
- this . mouseMove . next ( event ) ;
207
+ private checkEventListeners ( ) : void {
208
+
209
+ const canDrag : boolean = this . canDrag ( ) ;
210
+ const hasEventListeners : boolean = Object . keys ( this . eventListenerSubscriptions ) . length > 0 ;
211
+
212
+ if ( canDrag && ! hasEventListeners ) {
213
+
214
+ this . zone . runOutsideAngular ( ( ) => {
215
+
216
+ this . eventListenerSubscriptions . mousedown = this . renderer . listen ( this . element . nativeElement , 'mousedown' , ( event : MouseEvent ) => {
217
+ this . onMouseDown ( event ) ;
203
218
} ) ;
204
- }
205
- this . mouseDown . next ( event ) ;
206
- } ) ;
219
+
220
+ this . eventListenerSubscriptions . mouseup = this . renderer . listenGlobal ( 'document' , 'mouseup' , ( event : MouseEvent ) => {
221
+ this . onMouseUp ( event ) ;
222
+ } ) ;
223
+
224
+ this . eventListenerSubscriptions . mouseenter = this . renderer . listen ( this . element . nativeElement , 'mouseenter' , ( ) => {
225
+ this . onMouseEnter ( ) ;
226
+ } ) ;
227
+
228
+ this . eventListenerSubscriptions . mouseleave = this . renderer . listen ( this . element . nativeElement , 'mouseleave' , ( ) => {
229
+ this . onMouseLeave ( ) ;
230
+ } ) ;
231
+
232
+ } ) ;
233
+
234
+ } else if ( ! canDrag && hasEventListeners ) {
235
+ this . unsubscribeEventListeners ( ) ;
236
+ }
237
+
207
238
}
208
239
209
- /**
210
- * @hidden
211
- */
212
- @HostListener ( 'document:mouseup' , [ '$event' ] )
213
- onMouseUp ( event : MouseEvent ) : void {
214
- this . zone . runOutsideAngular ( ( ) => {
215
- if ( this . mouseMoveEventListenerUnsubscribe ) {
216
- this . mouseMoveEventListenerUnsubscribe ( ) ;
217
- this . mouseMoveEventListenerUnsubscribe = null ;
218
- }
219
- this . mouseUp . next ( event ) ;
220
- } ) ;
240
+ private onMouseDown ( event : MouseEvent ) : void {
241
+ if ( ! this . eventListenerSubscriptions . mousemove ) {
242
+ this . eventListenerSubscriptions . mousemove = this . renderer . listenGlobal ( 'document' , 'mousemove' , ( event : MouseEvent ) => {
243
+ this . mouseMove . next ( event ) ;
244
+ } ) ;
245
+ }
246
+ this . mouseDown . next ( event ) ;
221
247
}
222
248
223
- /**
224
- * @hidden
225
- */
226
- @HostListener ( 'mouseenter' )
227
- onMouseEnter ( ) : void {
228
- this . zone . runOutsideAngular ( ( ) => {
229
- if ( this . canDrag ( ) ) {
230
- this . setCursor ( MOVE_CURSOR ) ;
231
- }
232
- } ) ;
249
+ private onMouseUp ( event : MouseEvent ) : void {
250
+ if ( this . eventListenerSubscriptions . mousemove ) {
251
+ this . eventListenerSubscriptions . mousemove ( ) ;
252
+ delete this . eventListenerSubscriptions . mousemove ;
253
+ }
254
+ this . mouseUp . next ( event ) ;
233
255
}
234
256
235
- /**
236
- * @hidden
237
- */
238
- @HostListener ( 'mouseleave' )
239
- onMouseLeave ( ) : void {
240
- this . zone . runOutsideAngular ( ( ) => {
241
- this . setCursor ( null ) ;
242
- } ) ;
257
+ private onMouseEnter ( ) : void {
258
+ this . setCursor ( MOVE_CURSOR ) ;
259
+ }
260
+
261
+ private onMouseLeave ( ) : void {
262
+ this . setCursor ( null ) ;
243
263
}
244
264
245
265
private setCssTransform ( value : string ) : void {
@@ -260,4 +280,11 @@ export class Draggable implements OnInit, OnDestroy {
260
280
this . renderer . setElementStyle ( this . element . nativeElement , 'cursor' , value ) ;
261
281
}
262
282
283
+ private unsubscribeEventListeners ( ) : void {
284
+ Object . keys ( this . eventListenerSubscriptions ) . forEach ( ( type : string ) => {
285
+ this . eventListenerSubscriptions [ type ] ( ) ;
286
+ delete this . eventListenerSubscriptions [ type ] ;
287
+ } ) ;
288
+ }
289
+
263
290
}
0 commit comments