2016-03-02 35 views
6

Tôi đang cố triển khai chỉ thị kéo và thả tùy chỉnh. Nó hoạt động, nhưng nó là rất chậm, và tôi nghĩ rằng sự chậm chạp có thể được theo dõi để Angular 2 bởi vì tôi đã không bao giờ gặp phải sự chậm chạp này trước đây. Sự chậm chạp chỉ xảy ra khi tôi đính kèm trình xử lý sự kiện vào các sự kiện dragover hoặc drag (tức là các sự kiện được gửi thường xuyên), ngay cả khi tôi không làm gì ngoài việc trả về false trong đó.Góc 2 kéo và thả chỉ thị cực kỳ chậm

Đây là mã chỉ thị của tôi:

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

Đây là liên quan style sheet trích đoạn:

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

Như bạn có thể thấy tất cả những gì đang làm được nêu bật những yếu tố được kéo lên bằng màu vàng. Và nó hoạt động nhanh khi tôi không xử lý sự kiện dragover, tuy nhiên tôi phải xử lý sự kiện này để hỗ trợ giảm. Khi tôi xử lý sự kiện dragover, mọi thứ sẽ chậm lại đến mức không thể chịu nổi !!

EDIT Tôi đang sử dụng góc beta 2.0.0-beta.8

EDIT # 2 tôi đã cố gắng profiling mã sử dụng profiler chrome của, đây là kết quả:

Imgur

Nhìn vào dòng được đánh dấu, nó thật kỳ lạ ...

EDIT # 3 Tìm thấy vấn đề: nó thực sự là do phát hiện thay đổi của Angular 2. Thao tác kéo và thả trong trường hợp của tôi được thực hiện trên một trang rất dày đặc với rất nhiều ràng buộc và chỉ thị. Khi tôi nhận xét ra tất cả mọi thứ ngoại trừ danh sách nhất định, nó hoạt động nhanh trở lại ... Bây giờ tôi cần sự giúp đỡ của bạn trong việc tìm kiếm một giải pháp cho điều này!

EDIT # 4 SOLVED

Vấn đề đã thực sự thay đổi phát hiện, nhưng lỗi không phải với mã kiễu góc, nhưng thay vì với các ràng buộc không hiệu quả của riêng tôi. Tôi đã có nhiều ràng buộc của loại này:

*ngFor="#a of someFunc()" 

này gây ra góc để thể không chắc chắn cho dù dữ liệu đã thay đổi hay không, và các chức năng someFunc đã nhận được gọi là một lần nữa và một lần nữa mặc dù dữ liệu đã không được thay đổi trong thời gian kéo và quá trình thả . Tôi đã thay đổi các ràng buộc này để chỉ các thuộc tính đơn giản trong lớp của tôi, và di chuyển mã điền chúng vào nơi mà nó được cho là. Mọi thứ bắt đầu di chuyển nhanh như chớp một lần nữa!

Cảm ơn!

+1

bạn có thể giải thích một cách đơn giản những gì là nguyên nhân của vấn đề là gì? Tôi không thể hiểu được nhiều từ việc đọc vấn đề này ... –

+0

Rất có thể vì sự kết hợp của ng2 và jQuery, bạn đã thử chỉ dựa vào ng2 + RxJS? http://plnkr.co/edit/LD5FJaI4OOFbKfvhjD4e?p=preview –

+0

Đây không phải là nguyên nhân, xin lỗi, tôi đã thử xóa tất cả dấu vết của jQuery. Cùng một kết quả. –

Trả lời

4

Trả lời câu hỏi của riêng tôi (sự cố đã được giải quyết).

Vấn đề chậm là do các ràng buộc dữ liệu không hiệu quả trong đánh dấu của tôi, khiến Angular lãng phí rất nhiều thời gian gọi hàm trên mô hình khung nhìn của tôi.Tôi đã có nhiều ràng buộc của loại này:

*ngFor="#a of someFunc()" 

này gây ra góc để thể không chắc chắn cho dù dữ liệu đã thay đổi hay không, và các chức năng someFunc đã nhận được gọi là một lần nữa và một lần nữa sau mỗi lần chạy của onDragOver (mà là một khoảng một lần mỗi 350ms) mặc dù dữ liệu không thay đổi trong quá trình kéo và thả. Tôi đã thay đổi các ràng buộc này để chỉ các thuộc tính đơn giản trong lớp của tôi, và di chuyển mã điền chúng vào nơi mà nó được cho là. Mọi thứ bắt đầu di chuyển nhanh như chớp một lần nữa!

LLAP!

4

Chỉ cần trải qua một số sự cố với cùng một vấn đề. Ngay cả với mã hiệu quả ngFor, việc kéo và thả vẫn có thể bị chậm nếu bạn có một số lượng lớn các mục có thể kéo được.

Bí quyết đối với tôi là làm cho tất cả các trình xử lý sự kiện kéo và thả chạy bên ngoài Angular với ngZone, sau đó làm cho nó chạy trở lại trong Góc khi bị rớt. Điều này làm cho Angular tránh kiểm tra phát hiện cho mỗi pixel bạn di chuyển mục có thể kéo xung quanh.

Tiêm:

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

Khởi tạo:

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

On thả:

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

Cuối cùng là một giải pháp! Drag'nDrop đang chậm chạp trên một cấu trúc cây với nhiều ràng buộc liên quan. 10-15 giây quay các sự kiện 'kéo' không phải là ngoại lệ. Cảm ơn bạn. – passerby

+0

Giải pháp tuyệt vời. nó rất nhanh. –

0

Tôi đã có một vấn đề tương tự, cũng kéo và thả tôi trở nên rất chậm khi tôi đã đặt nhiều vùng kéo bên trong một *ngFor.

Tôi đã giải quyết vấn đề này bằng cách thay đổi chiến lược phát hiện thay đổi thành OnPush của thành phần con.

Sau đó, mỗi lần một mục bị kéo, hãy làm markForCheck().

constructor(private changeDetectorRef: ChangeDetectorRef) {} 
 
    
 
// Callback function 
 
public onDrag() { 
 
    this.changeDetectorRef.markForCheck(); 
 
}

Các vấn đề liên quan