我正在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
事件都运行更改检测。经过大量研究,我发现最好的解决方案应该是从ngzone中删除dragover
事件,这将防止触发更改检测。从这里:https://github.com/angular/angular/pull/21681
一种简单的方法似乎是(dragover.nozone)="stopAndPrevent($event)"
。这确实解决了性能问题,但由于浏览器将恢复为使用默认行为(在浏览器中加载文件)而忽略了event.preventDefault();
,因此它也不再起作用。有谁知道更好的方法或知道如何解决我在此处遇到的性能问题?
答案 0 :(得分: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
答案 1 :(得分:0)
您可以使用lodash-decorators中的节流阀。这样可以防止修饰后的函数运行的频率超过您作为参数指定的毫秒数。
@Throttle(300) public stopPreventAndSetClass(b: boolean, event: any): void {
//...
}