Created
November 15, 2018 23:00
-
-
Save shlomiassaf/49126eed76925a90ccfe6bb6c78bfddc to your computer and use it in GitHub Desktop.
Revisions
-
shlomiassaf created this gist
Nov 15, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,107 @@ import { take } from 'rxjs/operators'; import { Input, Directive, ElementRef, QueryList, OnDestroy, Optional, AfterViewInit } from '@angular/core'; import { CdkDropList, CdkDrag, CdkDragHandle, CDK_DROP_LIST_CONTAINER } from '@angular/cdk/drag-drop'; @Directive({ selector: '[cdkLazyDropList]', exportAs: 'cdkLazyDropList', providers: [ { provide: CDK_DROP_LIST_CONTAINER, useExisting: CdkLazyDropList }, ], host: { // tslint:disable-line:use-host-property-decorator 'class': 'cdk-drop-list', '[id]': 'id', '[class.cdk-drop-list-dragging]': '_dragging' } }) export class CdkLazyDropList<T = any> extends CdkDropList<T> { /** * Selector that will be used to determine the direct container element, starting from * the `cdkDropList` element and going down the DOM. Passing an alternate direct container element * is useful when the `cdkDropList` is not the direct parent (i.e. ancestor but not father) * of the draggable elements. */ // tslint:disable-next-line:no-input-rename @Input('cdkDropListDirectContainerElement') directContainerElement: string; _draggables: QueryList<CdkDrag>; private _draggablesSet = new Set<CdkDrag>(); // This is a workaround for https://github.com/angular/material2/pull/14153 // Working around the missing capability for selecting a container element that is not the drop container host. // The entire enter() overriding method can be removed if PR accepted, along with `directContainerElement` enter(item: CdkDrag, pointerX: number, pointerY: number): void { super.enter(item, pointerX, pointerY); if (this.directContainerElement) { const placeholder = item.getPlaceholderElement(); if (this.element.nativeElement.lastChild === placeholder) { const element = this.element.nativeElement.querySelector(this.directContainerElement); if (element) { element.appendChild(item.getPlaceholderElement()); } } } } addDrag(drag: CdkDrag): void { this._draggablesSet.add(drag); this._draggables.reset(Array.from(this._draggablesSet.values())); } removeDrag(drag: CdkDrag): boolean { const result = this._draggablesSet.delete(drag); if (result) { this._draggables.reset(Array.from(this._draggablesSet.values())); } return result; } } @Directive({ selector: '[cdkLazyDrag]', exportAs: 'cdkLazyDrag', host: { // tslint:disable-line:use-host-property-decorator 'class': 'cdk-drag', '[class.cdk-drag-dragging]': '_hasStartedDragging && _isDragging()', }, }) export class CdkLazyDrag<T = any, Z extends CdkLazyDropList<T> = CdkLazyDropList<T>> extends CdkDrag<T> implements AfterViewInit, OnDestroy { @Input() get cdkDropList(): Z { return this.dropContainer as Z; } set cdkDropList(value: Z) { // TO SUPPORT `cdkDropList` via string input (ID) we need a reactive registry... if (this.cdkDropList) { this.cdkDropList.removeDrag(this); } this.dropContainer = value; if (value) { value.addDrag(this); } } // This is a workaround for https://github.com/angular/material2/pull/14158 // Working around the issue of drop container is not the direct parent (father) of a drag item. // The entire ngAfterViewInit() overriding method can be removed if PR accepted. ngAfterViewInit(): void { this.started.subscribe( startedEvent => { if (this.dropContainer) { const element = this.getRootElement(); const initialRootElementParent = element.parentNode as HTMLElement; if (!element.nextSibling && initialRootElementParent !== this.dropContainer.element.nativeElement) { this.ended.pipe(take(1)).subscribe( endedEvent => initialRootElementParent.appendChild(element) ); } } }); super.ngAfterViewInit(); } ngOnDestroy(): void { if (this.cdkDropList) { this.cdkDropList.removeDrag(this); } super.ngOnDestroy(); } }