[英]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元素保留在內存中來解決這個問題,直到touchend
或touchcancel
事件。 但是,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事件的目標元素 。 然后在執行清理touchend
或touchcancel
(或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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.