拖放 – Angular 2拖放指令极其缓慢

前端之家收集整理的这篇文章主要介绍了拖放 – Angular 2拖放指令极其缓慢前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试实现自定义拖放指令.它有效,但它非常慢,我认为可以跟踪Angular 2的缓慢,因为我以前从未遇到过这种缓慢.只有当我将事件监听器附加到dragover或拖动事件(即频繁发送的事件)时,才会出现缓慢,即使我什么也不做,只是在其中返回false.

这是我的指令代码

import {Directive,ElementRef,Inject,Injectable} from 'angular2/core';

declare var jQuery: any;
declare var document: any;

@Directive({
    selector: '.my-log',host: {
        '(dragstart)': 'onDragStart($event)','(dragover)': 'onDragOver($event)','(dragleave)': 'onDragLeave($event)','(dragenter)': 'onDragEnter($event)','(drop)': 'onDrop($event)',}
})
@Injectable()
export class DraggableDirective {
    refcount = 0;
    jel;

    constructor( @Inject(ElementRef) private el: ElementRef) {
        el.nativeElement.setAttribute('draggable','true');
        this.jel = jQuery(el.nativeElement);
    }

    onDragStart(ev) {
        ev.dataTransfer.setData('Text',ev.target.id);
    }

    onDragOver(ev) {
        return false;
    }

    onDragEnter(ev) {
        if (this.refcount === 0) {
            this.jel.addClass('my-dragging-over');
        }
        this.refcount++;
    }

    onDragLeave(ev) {
        this.refcount--;
        if (this.refcount === 0) {
            this.jel.removeClass('my-dragging-over');
        }
    }

    onDrop(ev) {
        this.jel.removeClass('my-dragging-over');
        this.refcount = 0;
    }
}

这是相关的样式表摘录:

.my-log.my-dragging-over {
    background-color: yellow;
}

正如你所看到的,我正在做的是突出显示被黄色拖动的元素.当我不处理dragover事件时,它工作得很快,但我必须处理它以支持丢弃.当我处理dragover事件时,一切都会变慢到无法忍受的程度!

编辑我正在使用角度beta 2.0.0-beta.8

编辑#2我尝试使用chrome的分析器对代码进行分析,结果如下:

看看标记的线,这是奇怪的可疑……

编辑#3发现问题:这确实是由于Angular 2的变化检测.在我的案例中,拖放操作是在一个非常密集的页面上完成的,其中包含许多绑定和指令.当我评论除了给定列表之外的所有内容时,它再次快速运行……现在我需要你的帮助才能找到解决方案!

编辑#4已解决

问题确实是变化检测,但错误不是Angular的代码,而是我自己的低效绑定.我有很多这种绑定:

*ngFor="#a of someFunc()"

这导致Angular不确定数据是否已经改变,并且即使在拖放过程中数据没有改变,也会一次又一次地调用someFunc函数.我更改了这些绑定以引用我的类中的简单属性,并将填充它们的代码移动到它应该的位置.一切都开始快速闪电了!

谢谢!

刚遇到同样问题的麻烦.即使使用高效的ngFor代码,如果你有大量的可拖动项目,拖放仍然会很慢.

对我来说,诀窍是让所有拖放事件监听器都使用ngZone在Angular之外运行,然后在删除时使其在Angular中运行.这使得Angular可以避免检查您移动可拖动项目的每个像素.

注入:

import { Directive,NgZone } from '@angular/core';
constructor(private el: ElementRef,private ngZone: NgZone) {}

初始化:

ngOnInit() {
  this.ngZone.runOutsideAngular(() => {
    el.addEventListener('dragenter',(e) => {
      // do stuff with e or el
    });
...

在下降:

el.addEventListener('drop',(e) => {
    this.ngZone.run(() => {
        console.log("dropped");
    })
})

猜你在找的Angularjs相关文章