2016-08-05 79 views
1

我与Angular 2和触摸设备有问题。特别是,当一个组件通过NgFor渲染,并且(触摸)拖动屏幕。如果在触摸拖动过程中发生NgFor的重新呈现(由于外部事件更新绑定到NgFor的数据(这在我的应用中很常见),则会出现此问题。 touchmove事件停止发射,并要求您抬起手指并将其重新放回,这是一种可怕的移动体验。如果您使用鼠标,则不会发生此问题。有没有办法在Angular 2 RC5中防止DOM的移除?

本质上,在我的应用程序我听我的组件上的touchstart事件,经由有条件*ngIf="isDragging"示出了另一“DragComponent”(其不是NgFor内),它被移动大约基于所述touchmove事件位置数据的画面。

我知道为什么会发生这种情况。这是由于Touch Spec的浏览器实现。我通常在香草js中通过将DOM元素保存在内存中编码,直到touchendtouchcancel事件触发为止。不过,Angular现在控制着DOM!他们正在移除元素,而它仍然在使用中!

看看这个plunker http://plnkr.co/edit/QR6WDzv6NxOmn6LXTngG?p=preview得到更多的理解我想要描述的东西。 (注意:触摸屏需要,或使用在Chrome DevTools触摸仿真)

我也是在角回购所造成的问题#9864,但还没有得到任何回应。我知道他们正在为最终决定做准备,但在我看来这应该在最终决定之前解决,因为很多用户会在触摸设备上使用Angular。

我会很感激任何提示/解决方法/黑客。随意用解决方案更新解决方案。

回答

0

找到一个解决办法:

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

相关问题