首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >有什么方法可以防止角2 RC5中DOM的去除吗?

有什么方法可以防止角2 RC5中DOM的去除吗?
EN

Stack Overflow用户
提问于 2016-08-05 01:00:47
回答 1查看 408关注 0票数 1

我有角2和触摸设备的问题。特别是,当组件通过NgFor呈现并(触摸)拖动到屏幕上时。如果NgFor的重呈现发生在触摸拖动过程中(由于外部事件更新绑定到NgFor的数据,这在我的应用程序中很常见),就会出现这个问题。touchmove events停止触发,并要求您举起手指再次将其放回原处,这是一种糟糕的移动体验。如果使用鼠标,则不会发生此问题。

本质上,在我的应用程序中,我监听组件上的touchstart事件,通过一个条件*ngIf="isDragging" (它不在NgFor内)显示另一个'DragComponent‘,它是根据touchmove事件位置数据在屏幕上移动的。

我知道为什么会这样。这要归功于Touch Spec的浏览器实现。我通常使用vanilla编写这个问题的代码,方法是将DOM元素保存在内存中,直到touchendtouchcancel事件触发。然而,角现在控制DOM!他们正在删除元素时,它仍然在使用!

看看这个柱塞http://plnkr.co/edit/QR6WDzv6NxOmn6LXTngG?p=preview,更多地了解我想要描述的东西。(注意触摸屏需要,或者使用Chrome DevTools中的触摸仿真)

我还在“角度回购”中创建了一个问题#9864,但没有得到任何响应。我知道他们正忙着为决赛做准备,但在我看来,这应该在决赛之前解决,因为很多用户会在触摸设备上使用角度。

我希望有任何建议/解决办法/黑客。请随时使用解决方案更新柱塞。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-15 01:41:04

找到了一个解决办法:

实际上,TouchEvents在DOM删除之后确实会继续触发,但是它们只针对原始touchstart发生的节点/元素,并且不冒泡(不像MouseEvents,这让人困惑!)

因此,我们不能执行一个简单的@HostListener('touchmove', ['$event']),并期望它与DOM删除一起工作(因为事件侦听器附加到外部组件元素)。我们必须动态,将事件侦听器添加到touchstart事件的目标元素中。然后在touchendtouchcancel (或ngOnDestroy())上执行清理。

索伦:

代码语言:javascript
运行
复制
@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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38779609

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档