diff --git a/src/cdk/drag-drop/drag.spec.ts b/src/cdk/drag-drop/drag.spec.ts index c56a3526b64c..8538d42c3c58 100644 --- a/src/cdk/drag-drop/drag.spec.ts +++ b/src/cdk/drag-drop/drag.spec.ts @@ -578,6 +578,13 @@ describe('CdkDrag', () => { expect(dragElement.style.transform).toBe('translate3d(100px, 100px, 0px)'); })); + it('should throw if attached to an ng-container', fakeAsync(() => { + expect(() => { + createComponent(DraggableOnNgContainer).detectChanges(); + flush(); + }).toThrowError(/^cdkDrag must be attached to an element node/); + })); + }); describe('draggable with a handle', () => { @@ -2766,6 +2773,15 @@ class NestedDropListGroups { } +@Component({ + template: ` + + ` +}) +class DraggableOnNgContainer {} + + + /** * Component that passes through whatever content is projected into it. * Used to test having drag elements being projected into a component. diff --git a/src/cdk/drag-drop/drag.ts b/src/cdk/drag-drop/drag.ts index a59106226100..32dcd3a4e4ab 100644 --- a/src/cdk/drag-drop/drag.ts +++ b/src/cdk/drag-drop/drag.ts @@ -323,6 +323,12 @@ export class CdkDrag implements AfterViewInit, OnDestroy { .pipe(take(1)) .subscribe(() => { const rootElement = this._rootElement = this._getRootElement(); + + if (rootElement.nodeType !== this._document.ELEMENT_NODE) { + throw Error(`cdkDrag must be attached to an element node. ` + + `Currently attached to "${rootElement.nodeName}".`); + } + rootElement.addEventListener('mousedown', this._pointerDown, activeEventListenerOptions); rootElement.addEventListener('touchstart', this._pointerDown, passiveEventListenerOptions); this._handles.changes.pipe(startWith(null)).subscribe(() =>