@@ -26,6 +26,8 @@ import {
26
26
QueryList ,
27
27
SkipSelf ,
28
28
ViewContainerRef ,
29
+ OnChanges ,
30
+ SimpleChanges ,
29
31
} from '@angular/core' ;
30
32
import { coerceBooleanProperty } from '@angular/cdk/coercion' ;
31
33
import { Observable , Subscription , Observer } from 'rxjs' ;
@@ -70,7 +72,7 @@ export function CDK_DRAG_CONFIG_FACTORY(): DragRefConfig {
70
72
} ,
71
73
providers : [ { provide : CDK_DRAG_PARENT , useExisting : CdkDrag } ]
72
74
} )
73
- export class CdkDrag < T = any > implements AfterViewInit , OnDestroy {
75
+ export class CdkDrag < T = any > implements AfterViewInit , OnChanges , OnDestroy {
74
76
/** Subscription to the stream that initializes the root element. */
75
77
private _rootElementInitSubscription = Subscription . EMPTY ;
76
78
@@ -214,14 +216,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
214
216
this . _rootElementInitSubscription = this . _ngZone . onStable . asObservable ( )
215
217
. pipe ( take ( 1 ) )
216
218
. subscribe ( ( ) => {
217
- const rootElement = this . _getRootElement ( ) ;
218
-
219
- if ( rootElement . nodeType !== this . _document . ELEMENT_NODE ) {
220
- throw Error ( `cdkDrag must be attached to an element node. ` +
221
- `Currently attached to "${ rootElement . nodeName } ".` ) ;
222
- }
223
-
224
- this . _dragRef . withRootElement ( rootElement ) ;
219
+ this . _updateRootElement ( ) ;
225
220
this . _handles . changes
226
221
. pipe ( startWith ( this . _handles ) )
227
222
. subscribe ( ( handleList : QueryList < CdkDragHandle > ) => {
@@ -230,18 +225,33 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
230
225
} ) ;
231
226
}
232
227
228
+ ngOnChanges ( changes : SimpleChanges ) {
229
+ const rootSelectorChange = changes . rootElementSelector ;
230
+
231
+ // We don't have to react to the first change since it's being
232
+ // handled in `ngAfterViewInit` where it needs to be deferred.
233
+ if ( rootSelectorChange && ! rootSelectorChange . firstChange ) {
234
+ this . _updateRootElement ( ) ;
235
+ }
236
+ }
237
+
233
238
ngOnDestroy ( ) {
234
239
this . _rootElementInitSubscription . unsubscribe ( ) ;
235
240
this . _dragRef . dispose ( ) ;
236
241
}
237
242
238
- /** Gets the root draggable element, based on the `rootElementSelector `. */
239
- private _getRootElement ( ) : HTMLElement {
243
+ /** Syncs the root element with the `DragRef `. */
244
+ private _updateRootElement ( ) {
240
245
const element = this . element . nativeElement ;
241
246
const rootElement = this . rootElementSelector ?
242
- getClosestMatchingAncestor ( element , this . rootElementSelector ) : null ;
247
+ getClosestMatchingAncestor ( element , this . rootElementSelector ) : element ;
248
+
249
+ if ( rootElement && rootElement . nodeType !== this . _document . ELEMENT_NODE ) {
250
+ throw Error ( `cdkDrag must be attached to an element node. ` +
251
+ `Currently attached to "${ rootElement . nodeName } ".` ) ;
252
+ }
243
253
244
- return rootElement || element ;
254
+ this . _dragRef . withRootElement ( rootElement || element ) ;
245
255
}
246
256
247
257
/** Gets the boundary element, based on the `boundaryElementSelector`. */
0 commit comments