簡體   English   中英

有沒有辦法防止在Angular 2 RC5中刪除DOM?

[英]Is there a way to prevent DOM removal in Angular 2 RC5?

我遇到了Angular 2和觸控設備的問題 特別是,當通過NgFor渲染Component並且(觸摸)在屏幕上拖動時。 如果在觸摸拖動期間發生重新渲染NgFor(由於外部事件更新綁定到NgFor的數據,這在我的應用程序中很常見),就會出現問題。 touchmove事件停止發射 ,並要求您抬起手指並將其再次放下,這是一種糟糕的移動體驗。 如果您使用鼠標不會發生此問題。

基本上,在我的應用程序中,我在組件上偵聽touchstart事件,通過條件*ngIf="isDragging" (不在NgFor中)顯示另一個'DragComponent',並根據touchmove事件位置在屏幕上移動數據。

我知道為什么會這樣。 這是由於觸摸規范的瀏覽器實現。 我通常在vanilla js中通過將DOM元素保留在內存中來解決這個問題,直到touchendtouchcancel事件。 但是,Angular現在控制着DOM! 當它仍在使用時,它們正在移除元素!

查看這個plunker http://plnkr.co/edit/QR6WDzv6NxOmn6LXTngG?p=preview ,以便更好地了解我想要描述的內容。 需要注意觸摸屏 ,或在Chrome DevTools中使用Touch仿真)

我還在Angular回購中創建了一個問題#9864 ,但沒有任何回復。 我知道他們正忙着為最終做好准備,但在我看來,這應該在決賽前解決,因為很多用戶會在觸摸設備上使用Angular。

我很感激任何提示/解決方法/黑客攻擊。 隨意用解決方案更新plunker。

找到了一個解決方法:

TouchEvents做實際上繼續DOM取出后開火, 他們只在節點/元素針對性原來touchstart發生在和不冒泡(不像MouseEvents,這是混亂!)。

這樣,我們不能執行一個簡單的@HostListener('touchmove', ['$event'])並期望它與DOM去除工作(作為事件監聽器被附接到外部部件元素)。 我們有事件偵聽器,因為它們發生動態地添加到touchstart事件的目標元素 然后在執行清理touchendtouchcancel (或ngOnDestroy()

溶液:

@HostListener('touchstart', ['$event'])
@HostListener('mousedown', ['$event'])
  dragStart(event) {
    if (event.touches) {    // avoid touch event loss issue
      this.removePreviousTouchListeners();    // avoid mem leaks      
      this.touchmoveListenFunc = this.renderer.listen(event.target, 'touchmove', (e) => { this.onDragMove(e); });
      this.touchendListenFunc = this.renderer.listen(event.target, 'touchend', (e) => { this.removePreviousTouchListeners(); this.onDragEnd(e); });
      this.touchcancelListenFunc = this.renderer.listen(event.target, 'touchcancel', (e) => { this.removePreviousTouchListeners(); this.onDragEnd(e); });
    }
   ...
}

removePreviousTouchListeners() {
    if (this.touchmoveListenFunc !== null)
      this.touchmoveListenFunc();             // remove previous listener
    if (this.touchendListenFunc !== null)
      this.touchendListenFunc();              // remove previous listener
    if (this.touchcancelListenFunc !== null)
      this.touchcancelListenFunc();           // remove previous listener

    this.touchmoveListenFunc = null;
    this.touchendListenFunc = null;
    this.touchcancelListenFunc = null;
  }

 @HostListener('mousemove', ['$event'])
  // @HostListener('touchmove', ['$event'])    // don't declare this, as it is added dynamically
  onDragMove(event) {
    ...   // do stuff with event
  }

@HostListener('mouseup', ['$event'])
  // @HostListener('touchend', ['$event'])     // don't use these as they are added dynamically
  // @HostListener('touchcancel', ['$event']) // don't use these as they are added dynamically
  onDragEnd(event) {
    ...  // do stuff
  }

 ngOnDestroy() {
   this.removePreviousTouchListeners();

不要忘了注入Renderer在構造函數(進口@angular/core

來源https://plus.google.com/+RickByers/posts/GHwpqnAFATf

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM