Skip to content

Commit

Permalink
fix(drag-drop): error if drag sequence is started while another one i…
Browse files Browse the repository at this point in the history
…s finishing

Fixes an error being thrown if the user manages to start a different drag sequence while the previous one is finishing. The error comes from the fact that some elements are still being moved around while we're waiting for the previous animation to finish.

Fixes angular#13077.
  • Loading branch information
crisbeto committed May 21, 2019
1 parent 0908be7 commit 6b841c2
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
19 changes: 18 additions & 1 deletion src/cdk/drag-drop/directives/drag.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import {CdkDropListGroup} from './drop-list-group';
const ITEM_HEIGHT = 25;
const ITEM_WIDTH = 75;

describe('CdkDrag', () => {
fdescribe('CdkDrag', () => {
function createComponent<T>(
componentType: Type<T>, providers: Provider[] = [], dragDistance = 0,
extraDeclarations: Type<any>[] = []): ComponentFixture<T> {
Expand Down Expand Up @@ -2640,6 +2640,23 @@ describe('CdkDrag', () => {
}).not.toThrow();
}));

it('should not be able to start a drag sequence while another one is still active',
fakeAsync(() => {
const fixture = createComponent(DraggableInDropZone);
fixture.detectChanges();
const [item, otherItem] = fixture.componentInstance.dragItems.toArray();

startDraggingViaMouse(fixture, item.element.nativeElement);

expect(document.querySelectorAll('.cdk-drag-dragging').length)
.toBe(1, 'Expected one item to be dragged initially.');

startDraggingViaMouse(fixture, otherItem.element.nativeElement);

expect(document.querySelectorAll('.cdk-drag-dragging').length)
.toBe(1, 'Expected only one item to continue to be dragged.');
}));

});

describe('in a connected drop container', () => {
Expand Down
9 changes: 7 additions & 2 deletions src/cdk/drag-drop/drag-ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -510,8 +510,13 @@ export class DragRef<T = any> {
// in the `pointerMove` subscription, because we're not guaranteed to have one move event
// per pixel of movement (e.g. if the user moves their pointer quickly).
if (isOverThreshold && (Date.now() >= this._dragStartTime + (this.dragStartDelay || 0))) {
this._hasStartedDragging = true;
this._ngZone.run(() => this._startDragSequence(event));
// Prevent other drag sequences from starting while something in the container is still
// being dragged. This can happen while we're waiting for the drop animation to finish
// and can cause errors, because some elements might still be moving around.
if (!this._dropContainer || !this._dropContainer.isDragging()) {
this._hasStartedDragging = true;
this._ngZone.run(() => this._startDragSequence(event));
}
}

return;
Expand Down

0 comments on commit 6b841c2

Please sign in to comment.