0

我正在使用 Angular 7 尝试创建拖放文件上传组件。我让它在下面工作。

public stopPreventAndSetClass(b: boolean, event: any): void {
    if (event.target === this.enterTarget) {
        this.draggedOverTable = b;
    }
    console.log(event.target);
    this.stopAndPrevent(event);
}

public stopAndPrevent($event: any): void {
    event.preventDefault();
    event.stopPropagation();
}
<div class="document-container"
    (drop)="saveFiles($event); stopPreventAndSetClass(false, $event)"
    (dragenter)="enterTarget = $event.target; stopPreventAndSetClass(true, $event)"
    (dragover)="stopAndPrevent($event);"
    (dragleave)="stopPreventAndSetClass(false, $event)"
    [ngClass]="{'showDropContainerBorder': draggedOverTable}">
    <!-- An Angular Material table of uploaded files sits here. So think many child elements. -->
</div>

我的问题是这方面的性能很糟糕(drop 和 saveFiles() 运行之间的延迟时间约为 4 秒),因为每次触发的事件dragover都在运行更改检测。dragleave经过大量研究后,我发现最好的解决方案应该是dragover从 ngzone 中删除事件,这将阻止更改检测触发。从这里开始:https ://github.com/angular/angular/pull/21681 这样做的一个非常简单的方法似乎是(dragover.nozone)="stopAndPrevent($event)". 这确实解决了性能问题,但它也不再起作用,因为浏览器恢复为使用其默认行为(在浏览器中加载文件)忽略event.preventDefault();. 有谁知道更好的方法或知道如何解决我在这里遇到的性能问题?

4

2 回答 2

0

找到了解决方案。通过遵循https://github.com/JiaLiPassion/blacklist/blob/master/src/index.html并添加将zone.js 中的拖动事件列入黑名单

<script>
    var targets = [window, Document, HTMLBodyElement, HTMLElement];
    __Zone_ignore_on_properties = [];
    targets.forEach(function (target) {
      __Zone_ignore_on_properties.push({
        target: target,
        ignoreProperties: ['dragover']
      });
    });
    __zone_symbol__BLACK_LISTED_EVENTS = ['dragover'];
    __Zone_disable_requestAnimationFrame = true;
</script>

到我的 index.html

于 2019-01-02T19:24:12.983 回答
0

您可以使用lodash-decorators 的节流阀。它将防止装饰函数的运行频率超过您作为参数提供的毫秒数。

@Throttle(300) public stopPreventAndSetClass(b: boolean, event: any): void {
   //...
}
于 2019-01-02T21:48:53.600 回答