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

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

问题描述

我正在尝试实现自定义拖放指令。它的工作原理非常慢,我认为慢速度可以追溯到角度2,因为我之前从来没有遇到这么慢。缓慢只发生在我将事件监听器附加到 dragover 拖动事件(即频繁发送的事件)时),即使我什么都不做,只是返回 false

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!!

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

EDIT I am using angular beta 2.0.0-beta.8

编辑#2 我尝试使用chrome的profiler对代码进行分析,这些是结果:

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

查看标记行,这是奇怪的可疑...

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

编辑#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!

问题确实是更改检测,但是错误并不是Angular的代码,而是我自己无效的绑定。我有很多这样的绑定:

The problem was indeed change detection, but the fault wasn't with Angular's code, but rather with my own inefficient bindings. I had many bindings of this sort:

*ngFor="#a of someFunc()"

这导致Angular不确定数据是否已更改,函数 someFunc 也被重新呼叫。我改变了这些绑定,以引用我的类中的简单属性,并移动了将它们填充到应该是的位置的代码。一切都开始快速闪电了!

This caused Angular to be unsure whether data has changed or not, and the function someFunc was getting called again and again 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!

谢谢!

推荐答案

我自己的问题(问题已解决)。

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不确定数据是否已更改,函数 someFunc 在每次运行 onDragOver (即每350ms约一次)之后,即使数据在拖放过程中没有更改,也被一再呼叫。我改变了这些绑定,以引用我的类中的简单属性,并移动了将它们填充到应该是的位置的代码。一切开始快速移动闪电!

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!

LLAP!

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

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