fix(drag-drop): standalone draggable drag class not being applied with OnPush change detection (#14727)

Fixes the styling that is applied while an item is dragged not being applied with `OnPush` change detection.
This commit is contained in:
Kristiyan Kostadinov
2019-02-07 20:55:02 +01:00
committed by Jeremy Elbourn
parent 456a0893d8
commit 8ddcb5ba20
3 changed files with 52 additions and 9 deletions
+30
View File
@@ -461,6 +461,25 @@ describe('CdkDrag', () => {
expect(element.classList).not.toContain('cdk-drag-dragging');
}));
it('should add a class while an element is being dragged with OnPush change detection',
fakeAsync(() => {
const fixture = createComponent(StandaloneDraggableWithOnPush);
fixture.detectChanges();
const element = fixture.componentInstance.dragElement.nativeElement;
expect(element.classList).not.toContain('cdk-drag-dragging');
startDraggingViaMouse(fixture, element);
expect(element.classList).toContain('cdk-drag-dragging');
dispatchMouseEvent(document, 'mouseup');
fixture.detectChanges();
expect(element.classList).not.toContain('cdk-drag-dragging');
}));
it('should not add a class if item was not dragged more than the threshold', fakeAsync(() => {
const fixture = createComponent(StandaloneDraggable, [], 5);
fixture.detectChanges();
@@ -2830,6 +2849,17 @@ class StandaloneDraggable {
boundarySelector: string;
}
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div cdkDrag #dragElement style="width: 100px; height: 100px; background: red;"></div>
`
})
class StandaloneDraggableWithOnPush {
@ViewChild('dragElement') dragElement: ElementRef<HTMLElement>;
@ViewChild(CdkDrag) dragInstance: CdkDrag;
}
@Component({
template: `
<svg><g
+21 -8
View File
@@ -28,6 +28,7 @@ import {
ViewContainerRef,
OnChanges,
SimpleChanges,
ChangeDetectorRef,
} from '@angular/core';
import {coerceBooleanProperty} from '@angular/cdk/coercion';
import {Observable, Observer, Subject, merge} from 'rxjs';
@@ -175,11 +176,12 @@ export class CdkDrag<T = any> implements AfterViewInit, OnChanges, OnDestroy {
@Optional() private _dir: Directionality,
/**
* @deprecated `viewportRuler` and `dragDropRegistry` parameters
* @deprecated `viewportRuler`, `dragDropRegistry` and `_changeDetectorRef` parameters
* to be removed. Also `dragDrop` parameter to be made required.
* @breaking-change 8.0.0.
*/
dragDrop?: DragDrop) {
dragDrop?: DragDrop,
private _changeDetectorRef?: ChangeDetectorRef) {
// @breaking-change 8.0.0 Remove null check once the paramter is made required.
@@ -192,7 +194,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnChanges, OnDestroy {
this._dragRef.data = this;
this._syncInputs(this._dragRef);
this._proxyEvents(this._dragRef);
this._handleEvents(this._dragRef);
}
/**
@@ -313,13 +315,17 @@ export class CdkDrag<T = any> implements AfterViewInit, OnChanges, OnDestroy {
});
}
/**
* Proxies the events from a DragRef to events that
* match the interfaces of the CdkDrag outputs.
*/
private _proxyEvents(ref: DragRef<CdkDrag<T>>) {
/** Handles the events from the underlying `DragRef`. */
private _handleEvents(ref: DragRef<CdkDrag<T>>) {
ref.started.subscribe(() => {
this.started.emit({source: this});
// Since all of these events run outside of change detection,
// we need to ensure that everything is marked correctly.
if (this._changeDetectorRef) {
// @breaking-change 8.0.0 Remove null check for _changeDetectorRef
this._changeDetectorRef.markForCheck();
}
});
ref.released.subscribe(() => {
@@ -328,6 +334,13 @@ export class CdkDrag<T = any> implements AfterViewInit, OnChanges, OnDestroy {
ref.ended.subscribe(() => {
this.ended.emit({source: this});
// Since all of these events run outside of change detection,
// we need to ensure that everything is marked correctly.
if (this._changeDetectorRef) {
// @breaking-change 8.0.0 Remove null check for _changeDetectorRef
this._changeDetectorRef.markForCheck();
}
});
ref.entered.subscribe(event => {
+1 -1
View File
@@ -28,7 +28,7 @@ export declare class CdkDrag<T = any> implements AfterViewInit, OnChanges, OnDes
constructor(
element: ElementRef<HTMLElement>,
dropContainer: CdkDropList, _document: any, _ngZone: NgZone, _viewContainerRef: ViewContainerRef, viewportRuler: ViewportRuler, dragDropRegistry: DragDropRegistry<DragRef, DropListRef>, config: DragRefConfig, _dir: Directionality,
dragDrop?: DragDrop);
dragDrop?: DragDrop, _changeDetectorRef?: ChangeDetectorRef | undefined);
getPlaceholderElement(): HTMLElement;
getRootElement(): HTMLElement;
ngAfterViewInit(): void;