文件拖放,mat扩展面板和Angular CDK覆盖问题(两次发动射击)问题

时间:2019-08-14 12:38:21

标签: angular overlay angular-directive angular-cdk dragenter

我在放下文件时出现了两倍重叠的问题。

用户可以拖放文件。拖动文件时,在特定区域中应该有一个叠加层,上面显示消息“在此处拖动文件”(仅在可以放置文件的地方)。我写了一条指令来处理这种行为。

file-upload.directive.ts:

import { Overlay, OverlayRef, PositionStrategy } from '@angular/cdk/overlay';
import { TemplatePortal } from '@angular/cdk/portal';
import { ComponentFactoryResolver, Directive, Input, NgZone, OnDestroy, OnInit, TemplateRef, ViewContainerRef } from '@angular/core';
import { FileUploadComponent } from './file-upload.component';
import { Subject, Subscription } from 'rxjs';

@Directive({
    selector: '[fileUpload]',
})
export class FileUploadDirective implements OnInit, OnDestroy {
    private _overlayRef: OverlayRef;
    private _onDestroy$ = new Subject();
    private _dragEventsCollection = [];
    private _fileUploadComponent: FileUploadComponent;
    private _status: boolean = false;

    constructor(
        private _hostTemplate: TemplateRef<any>,
        private _hostViewContainer: ViewContainerRef,
        private _resolver: ComponentFactoryResolver,
        private _overlayService: Overlay
    ) { }

    ngOnInit(): void {

        // Creating ng-template contents (host element)
        this._hostViewContainer.createEmbeddedView(this._hostTemplate);

        // Creating file-drop component
        this._fileUploadComponent = this._hostViewContainer
            .createComponent(this._resolver.resolveComponentFactory(FileUploadComponent))
            .instance;        

        document.addEventListener('dragenter', e => {
          console.log('dragEventCollection.length: ', this._dragEventsCollection.length);
            if (this._dragEventsCollection.length === 0) {
              console.warn('Opening overlay. Event: ', e);
                this.openOverlay();
                // this removes the second event - however the second event triggers correct overlay and the first one not
                // e.stopImmediatePropagation() ;
            }
            this._dragEventsCollection.push(e.target);
        });

        document.addEventListener('dragleave', e => {
            const index = this._dragEventsCollection.indexOf(e.target);
            this._dragEventsCollection.splice(index, 1);
            if (this._dragEventsCollection.length === 0) {
                this.closeOverlay();
            }
        });
    }

    ngOnDestroy(): void {
        this._onDestroy$.next();
        this._onDestroy$.unsubscribe();
        this._onDestroy$ = null;
    }

    openOverlay() {
        const cdkOverlayOrigin = this._hostTemplate.elementRef.nativeElement.nextElementSibling;
        let positionStrategy: PositionStrategy;

        if (this._overlayRef === undefined) {
            positionStrategy = this._overlayService.position()
                .flexibleConnectedTo(cdkOverlayOrigin)
                .withPush(false)
                .withGrowAfterOpen(true)
                .withPositions([{
                    originX: 'start',
                    originY: 'top',
                    overlayX: 'start',
                    overlayY: 'top',
                }]);

            this._overlayRef = this._overlayService.create({
                positionStrategy,
                scrollStrategy: this._overlayService.scrollStrategies.block(),
            });
        }

        if (!!this._overlayRef && !this._overlayRef.hasAttached()) {
            this._overlayRef.attach(new TemplatePortal(this._fileUploadComponent.overlayTemplate, this._hostViewContainer));
            this._overlayRef.updateSize({
                width: cdkOverlayOrigin.clientWidth,
                height: cdkOverlayOrigin.clientHeight
            }
            );
        }
        console.warn('OverlayRef: ', this._overlayRef);
    }

    closeOverlay() {
        if (!!this._overlayRef && this._overlayRef.hasAttached()) {
            this._overlayRef.detach();
        }
    }
}

问题是我收到2条通知(两个覆盖图): enter image description here

我注意到Dragenter事件触发了两次,这导致创建了两个覆盖面板: enter image description here

这发生在Angular 7和8上。

具有完整示例代码的https://stackblitz.com/edit/epxansion-with-overlay-3-8esk4u

已经花费了几个小时试图弄清楚发生了什么。任何想法将不胜感激。

谢谢!

0 个答案:

没有答案