Angular 2 拖放指令非常慢 [英] Angular 2 drag and drop directive extremely slow

查看:18
本文介绍了Angular 2 拖放指令非常慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现自定义拖放指令.它有效,但速度非常慢,我认为可以将慢度跟踪到 Angular 2,因为我以前从未遇到过这种慢度.只有当我将事件侦听器附加到 dragoverdrag 事件(即频繁发送的事件)时才会发生缓慢,即使我只返回 错误在他们.

I am trying to implement a custom drag and drop directive. It works, but it is extremely slow, and I think the slowness can be tracked to Angular 2 because I've never encountered this slowness before. The slowness only occurs when I attach an event listener to the dragover or drag events (i.e. the events which are sent frequently), even if I do nothing but return false in them.

这是我的指令代码:

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;
    }
}

这是相关的样式表摘录:

Here's the relevant style sheet excerpt:

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

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

As you can see all I'm doing is highlighting the element being dragged over in yellow. And it works fast when I don't handle the dragover event, however I must handle it to support dropping. When I do handle the dragover event, everything slows down to unbearable levels!!

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

EDIT I am using angular beta 2.0.0-beta.8

EDIT #2 我尝试使用 chrome 的分析器分析代码,结果如下:

EDIT #2 I tried profiling the code using chrome's profiler, these are the results:

看标记的线,奇怪的可疑...

Look at the marked line, it is strangely suspicious...

EDIT #3 发现问题:确实是由于 Angular 2 的更改检测.在我的案例中,拖放操作是在具有大量绑定和指令的非常密集的页面上完成的.当我注释掉除给定列表之外的所有内容时,它再次快速运行......现在我需要你的帮助来找到解决方案!

EDIT #3 Found the problem: it was indeed due to Angular 2's change detection. The drag and drop operation in my case is done on a very dense page with a lot of bindings and directives. When I commented out everything except the given list, it worked fast again... Now I need your help in finding a solution to this!

推荐答案

回答我自己的问题(问题已解决).

Answering my own question (problem was solved).

缓慢的问题是由于我的标记中的数据绑定效率低下,这导致 Angular 浪费大量时间在我的视图模型上调用函数.我有很多这样的绑定:

The slowness problem was due to inefficient data bindings in my markup, which caused Angular to waste a lot of time calling functions on my view model. I had many bindings of this sort:

*ngFor="#a of someFunc()"

这导致 Angular 不确定数据是否已更改,并且在每次运行 onDragOver 后,函数 someFunc 都会被一次又一次地调用(这是一个关于每 350 毫秒一次),即使数据在拖放过程中没有变化.我更改了这些绑定以引用我的类中的简单属性,并将填充它们的代码移动到它应该在的位置.一切又开始如闪电般快速移动!

This caused Angular to be unsure whether data has changed or not, and the function someFunc was getting called again and again after every run of onDragOver (which is a about once every 350ms) even though data was not changing during the drag and drop process. I changed these bindings to refer to simple properties in my class, and moved the code that populates them where it was supposed to be. Everything started moving lightning fast again!

这篇关于Angular 2 拖放指令非常慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆