Skip to content

Commit a7276fd

Browse files
committed
fix(drag-drop): remove circular dependencies
Currently we've got the following circular dependencies in master, after the `CdkDragDropRegistry` got introduced: ``` drop.ts -> drag.ts -> drag-drop-registry.ts -> drop.ts drag.ts -> drag-drop-registry.ts -> drag.ts drop.ts -> drag-drop-registry.ts -> drop.ts ``` These changes rework the registry to avoid importing `CdkDrag` and `CdkDrop`, in order to break the circular references.
1 parent 1e1751f commit a7276fd

File tree

5 files changed

+64
-71
lines changed

5 files changed

+64
-71
lines changed

src/cdk-experimental/drag-drop/drag-drop-registry.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {CdkDrop} from './drop';
1414
describe('DragDropRegistry', () => {
1515
let fixture: ComponentFixture<SimpleDropZone>;
1616
let testComponent: SimpleDropZone;
17-
let registry: CdkDragDropRegistry;
17+
let registry: CdkDragDropRegistry<CdkDrag, CdkDrop>;
1818

1919
beforeEach(fakeAsync(() => {
2020
TestBed.configureTestingModule({
@@ -26,7 +26,7 @@ describe('DragDropRegistry', () => {
2626
testComponent = fixture.componentInstance;
2727
fixture.detectChanges();
2828

29-
inject([CdkDragDropRegistry], (c: CdkDragDropRegistry) => {
29+
inject([CdkDragDropRegistry], (c: CdkDragDropRegistry<CdkDrag, CdkDrop>) => {
3030
registry = c;
3131
})();
3232
}));
@@ -59,7 +59,7 @@ describe('DragDropRegistry', () => {
5959
registry.startDragging(firstItem, createMouseEvent('mousedown'));
6060
expect(registry.isDragging(firstItem)).toBe(true);
6161

62-
registry.remove(firstItem);
62+
registry.removeDragItem(firstItem);
6363
expect(registry.isDragging(firstItem)).toBe(false);
6464
});
6565

@@ -130,7 +130,7 @@ describe('DragDropRegistry', () => {
130130
});
131131

132132
it('should not throw when trying to register the same container again', () => {
133-
expect(() => registry.register(testComponent.dropInstances.first)).not.toThrow();
133+
expect(() => registry.registerDropContainer(testComponent.dropInstances.first)).not.toThrow();
134134
});
135135

136136
it('should throw when trying to register a different container with the same id', () => {

src/cdk-experimental/drag-drop/drag-drop-registry.ts

Lines changed: 51 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ import {Injectable, NgZone, OnDestroy, Inject} from '@angular/core';
1010
import {DOCUMENT} from '@angular/common';
1111
import {supportsPassiveEventListeners} from '@angular/cdk/platform';
1212
import {Subject} from 'rxjs';
13-
import {CdkDrop} from './drop';
14-
import {CdkDrag} from './drag';
1513

1614
/** Event options that can be used to bind an active event. */
1715
const activeEventOptions = supportsPassiveEventListeners() ? {passive: false} : false;
@@ -20,35 +18,35 @@ const activeEventOptions = supportsPassiveEventListeners() ? {passive: false} :
2018
type PointerEventHandler = (event: TouchEvent | MouseEvent) => void;
2119

2220
/**
23-
* Service that keeps track of all the `CdkDrag` and `CdkDrop` instances, and
24-
* manages global event listeners on the `document`.
21+
* Service that keeps track of all the drag item and drop container
22+
* instances, and manages global event listeners on the `document`.
2523
* @docs-private
2624
*/
2725
@Injectable({providedIn: 'root'})
28-
export class CdkDragDropRegistry implements OnDestroy {
26+
export class CdkDragDropRegistry<I, C extends {id: string}> implements OnDestroy {
2927
private _document: Document;
3028

31-
/** Registered `CdkDrop` instances. */
32-
private _dropInstances = new Set<CdkDrop>();
29+
/** Registered drop container instances. */
30+
private _dropInstances = new Set<C>();
3331

34-
/** Registered `CdkDrag` instances. */
35-
private _dragInstances = new Set<CdkDrag>();
32+
/** Registered drag item instances. */
33+
private _dragInstances = new Set<I>();
3634

37-
/** `CdkDrag` instances that are currently being dragged. */
38-
private _activeDragInstances = new Set<CdkDrag>();
35+
/** Drag item instances that are currently being dragged. */
36+
private _activeDragInstances = new Set<I>();
3937

4038
/** Keeps track of the event listeners that we've bound to the `document`. */
4139
private _globalListeners = new Map<string, {handler: PointerEventHandler, options?: any}>();
4240

4341
/**
4442
* Emits the `touchmove` or `mousemove` events that are dispatched
45-
* while the user is dragging a `CdkDrag` instance.
43+
* while the user is dragging a drag item instance.
4644
*/
4745
readonly pointerMove: Subject<TouchEvent | MouseEvent> = new Subject<TouchEvent | MouseEvent>();
4846

4947
/**
5048
* Emits the `touchend` or `mouseup` events that are dispatched
51-
* while the user is dragging a `CdkDrag` instance.
49+
* while the user is dragging a drag item instance.
5250
*/
5351
readonly pointerUp: Subject<TouchEvent | MouseEvent> = new Subject<TouchEvent | MouseEvent>();
5452

@@ -58,52 +56,44 @@ export class CdkDragDropRegistry implements OnDestroy {
5856
this._document = _document;
5957
}
6058

61-
/** Adds a `CdkDrop` instance to the registry. */
62-
register(drop: CdkDrop);
63-
64-
/** Adds a `CdkDrag` instance to the registry. */
65-
register(drag: CdkDrag);
66-
67-
register(instance: CdkDrop | CdkDrag) {
68-
if (instance instanceof CdkDrop) {
69-
if (!this._dropInstances.has(instance)) {
70-
if (this.getDropContainer(instance.id)) {
71-
throw Error(`Drop instance with id "${instance.id}" has already been registered.`);
72-
}
73-
74-
this._dropInstances.add(instance);
75-
}
76-
} else {
77-
this._dragInstances.add(instance);
78-
79-
if (this._dragInstances.size === 1) {
80-
this._ngZone.runOutsideAngular(() => {
81-
// The event handler has to be explicitly active, because
82-
// newer browsers make it passive by default.
83-
this._document.addEventListener('touchmove', this._preventScrollListener,
84-
activeEventOptions);
85-
});
59+
/** Adds a drop container to the registry. */
60+
registerDropContainer(drop: C) {
61+
if (!this._dropInstances.has(drop)) {
62+
if (this.getDropContainer(drop.id)) {
63+
throw Error(`Drop instance with id "${drop.id}" has already been registered.`);
8664
}
65+
66+
this._dropInstances.add(drop);
8767
}
8868
}
8969

90-
/** Removes a `CdkDrop` instance from the registry. */
91-
remove(drop: CdkDrop);
70+
/** Adds a drag item instance to the registry. */
71+
registerDragItem(drag: I) {
72+
this._dragInstances.add(drag);
73+
74+
if (this._dragInstances.size === 1) {
75+
this._ngZone.runOutsideAngular(() => {
76+
// The event handler has to be explicitly active, because
77+
// newer browsers make it passive by default.
78+
this._document.addEventListener('touchmove', this._preventScrollListener,
79+
activeEventOptions);
80+
});
81+
}
82+
}
9283

93-
/** Removes a `CdkDrag` instance from the registry. */
94-
remove(drag: CdkDrag);
84+
/** Removes a drop container from the registry. */
85+
removeDropContainer(drop: C) {
86+
this._dropInstances.delete(drop);
87+
}
9588

96-
remove(instance: CdkDrop | CdkDrag) {
97-
if (instance instanceof CdkDrop) {
98-
this._dropInstances.delete(instance);
99-
} else {
100-
this._dragInstances.delete(instance);
101-
this.stopDragging(instance);
89+
/** Removes a drag item instance from the registry. */
90+
removeDragItem(drag: I) {
91+
this._dragInstances.delete(drag);
92+
this.stopDragging(drag);
10293

103-
if (this._dragInstances.size === 0) {
104-
this._document.removeEventListener('touchmove', this._preventScrollListener,
105-
activeEventOptions as any);
106-
}
94+
if (this._dragInstances.size === 0) {
95+
this._document.removeEventListener('touchmove', this._preventScrollListener,
96+
activeEventOptions as any);
10797
}
10898
}
10999

@@ -112,7 +102,7 @@ export class CdkDragDropRegistry implements OnDestroy {
112102
* @param drag Drag instance which is being dragged.
113103
* @param event Event that initiated the dragging.
114104
*/
115-
startDragging(drag: CdkDrag, event: TouchEvent | MouseEvent) {
105+
startDragging(drag: I, event: TouchEvent | MouseEvent) {
116106
this._activeDragInstances.add(drag);
117107

118108
if (this._activeDragInstances.size === 1) {
@@ -134,28 +124,28 @@ export class CdkDragDropRegistry implements OnDestroy {
134124
}
135125
}
136126

137-
/** Stops dragging a `CdkDrag` instance. */
138-
stopDragging(drag: CdkDrag) {
127+
/** Stops dragging a drag item instance. */
128+
stopDragging(drag: I) {
139129
this._activeDragInstances.delete(drag);
140130

141131
if (this._activeDragInstances.size === 0) {
142132
this._clearGlobalListeners();
143133
}
144134
}
145135

146-
/** Gets whether a `CdkDrag` instance is currently being dragged. */
147-
isDragging(drag: CdkDrag) {
136+
/** Gets whether a drag item instance is currently being dragged. */
137+
isDragging(drag: I) {
148138
return this._activeDragInstances.has(drag);
149139
}
150140

151-
/** Gets a `CdkDrop` instance by its id. */
152-
getDropContainer<T = any>(id: string): CdkDrop<T> | undefined {
141+
/** Gets a drop container by its id. */
142+
getDropContainer(id: string): C | undefined {
153143
return Array.from(this._dropInstances).find(instance => instance.id === id);
154144
}
155145

156146
ngOnDestroy() {
157-
this._dragInstances.forEach(instance => this.remove(instance));
158-
this._dropInstances.forEach(instance => this.remove(instance));
147+
this._dragInstances.forEach(instance => this.removeDragItem(instance));
148+
this._dropInstances.forEach(instance => this.removeDropContainer(instance));
159149
this._clearGlobalListeners();
160150
this.pointerMove.complete();
161151
this.pointerUp.complete();

src/cdk-experimental/drag-drop/drag.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,10 @@ export class CdkDrag<T = any> implements OnDestroy {
138138
private _ngZone: NgZone,
139139
private _viewContainerRef: ViewContainerRef,
140140
private _viewportRuler: ViewportRuler,
141-
private _dragDropRegistry: CdkDragDropRegistry,
141+
private _dragDropRegistry: CdkDragDropRegistry<CdkDrag<T>, CdkDropContainer>,
142142
@Optional() private _dir: Directionality) {
143143
this._document = document;
144-
_dragDropRegistry.register(this);
144+
_dragDropRegistry.registerDragItem(this);
145145
}
146146

147147
/**
@@ -165,7 +165,7 @@ export class CdkDrag<T = any> implements OnDestroy {
165165
}
166166

167167
this._nextSibling = null;
168-
this._dragDropRegistry.remove(this);
168+
this._dragDropRegistry.removeDragItem(this);
169169
this._destroyed.next();
170170
this._destroyed.complete();
171171
}

src/cdk-experimental/drag-drop/drop-container.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ export interface CdkDropContainer<T = any> {
1313
/** Arbitrary data to attach to all events emitted by this container. */
1414
data: T;
1515

16+
/** Unique ID for the drop zone. */
17+
id: string;
18+
1619
/** Direction in which the list is oriented. */
1720
orientation: 'horizontal' | 'vertical';
1821

src/cdk-experimental/drag-drop/drop.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,14 @@ export class CdkDrop<T = any> implements OnInit, OnDestroy {
8585

8686
constructor(
8787
public element: ElementRef<HTMLElement>,
88-
private _dragDropRegistry: CdkDragDropRegistry) {}
88+
private _dragDropRegistry: CdkDragDropRegistry<CdkDrag, CdkDrop<T>>) {}
8989

9090
ngOnInit() {
91-
this._dragDropRegistry.register(this);
91+
this._dragDropRegistry.registerDropContainer(this);
9292
}
9393

9494
ngOnDestroy() {
95-
this._dragDropRegistry.remove(this);
95+
this._dragDropRegistry.removeDropContainer(this);
9696
}
9797

9898
/** Whether an item in the container is being dragged. */

0 commit comments

Comments
 (0)