Угловой компонент загрузки файлов.nozone
Я работаю в 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>
Моя проблема в том, что производительность на этом ужасна (~4-секундное время задержки между drop и saveFiles() работает), потому что обнаружение изменений работает для каждого dragover
а также dragleave
Событие сработало. Проведя большое количество исследований, я обнаружил, что лучшим решением, как предполагается, является удаление dragover
событие из зоны ngzone, которое предотвратит срабатывание обнаружения изменений. Отсюда: https://github.com/angular/angular/pull/21681 Очень простой способ сделать это, кажется, (dragover.nozone)="stopAndPrevent($event)"
, Это решает проблему производительности, но также больше не работает, поскольку браузер возвращается к использованию по умолчанию (загрузка файла в браузер), игнорируя event.preventDefault();
, Кто-нибудь знает лучший способ сделать это или знает, как исправить проблему с производительностью, с которой я здесь сталкиваюсь?
2 ответа
Вы можете использовать дроссель от lodash-декораторов. Это предотвратит выполнение декорированной функции чаще, чем количество миллисекунд, которое вы указываете в качестве параметра.
@Throttle(300) public stopPreventAndSetClass(b: boolean, event: any): void {
//...
}
Нашел решение. Внесение в черный список событий dragover из zone.js, выполнив https://github.com/JiaLiPassion/blacklist/blob/master/src/index.html и добавив
<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