[bug core] *ngFor + Touch Issue
See original GitHub issueI’m submitting a …
[x] bug report
Current behavior
If I drag a component, bound within an *ngFor
, (using a touchscreen) and an external event causes the ngFor array to update, touchmove
events stop firing. This is a terrible experience on mobile. Angular 2 is nearing official release and I’m concerned how to fix the mobile experience. Mouse dragging does not have this issue.
E.g. I have a data array, currentBookings = [{..}, {..}]
, that is bound with an *ngFor
such as
<booking *ngFor="let booking of currentBookings"></booking>
and I drag one of the generated <booking>
components to the ‘nextDay’ button, which causes the currentBookings
array to update. See this Plunker
- I have dealt with this (Touch Spec / Browser Implementation) issue in the past (vanilla JS) by simply keeping the DOM element reference around until the
touchend
ortouchcancel
event fire. - However, Angular controls the DOM now !
- Could this be solved by Angular implementing a
canDestroy()
Component guard (i.e not route guard) ???
Expected/desired behavior
A canDestroy()
Component guard. Or any solution that avoids premature DOM removal of an element. Angular could keep the DOM element in memory and set a style of {display: none;}
. Anything to improve the drag experience on mobile…which is pretty important in my opinion.
Reproduction of the problem
See this Plunker. Note: Touchscreen required (or Chrome Dev Tools mobile emulation)
What is the expected behavior?
In my Plunker, I expect the touchmove
events to keep firing after dragging the ‘booking’ to the next/prev day. It works as expected with mouse dragging.
What is the motivation / use case for changing the behavior?
Improve the mobile experience of Angular 2.
Environment:
- Angular version: 2.0.0-rc.4
- Browser: [Chrome 51 (with touchscreen), iOS 9.3.2 Safari]
- Language: Typescript@1.9.0-dev.20160409 see plunker
Issue Analytics
- State:
- Created 7 years ago
- Reactions:5
- Comments:6 (1 by maintainers)
Found a workaround:
TouchEvents do actually continue to fire after DOM removal BUT they are only targeted at the node/element that the original
touchstart
occurred on and don’t bubble (unlike MouseEvents, which is confusing!).So, we cant perform a simple
@HostListener('touchmove', ['$event'])
and expect it to work with DOM removal (as the event listener is attached to the outer component element). We have to dynamically add event listeners to the target element of the touchstart event as they occur. Then perform cleanup ontouchend
ortouchcancel
(orngOnDestroy()
).Solution:
Don’t forget to inject
Renderer
in the constructor (import from@angular/core
Source https://plus.google.com/+RickByers/posts/GHwpqnAFATf
@vicb listed above http://plnkr.co/edit/QR6WDzv6NxOmn6LXTngG?p=preview
See my above workaround too.
If #10834 gets implemented, this issue would go away.