How to handle hybrid devices in click/touch events properly?
You could use a Subject and debounce for a couple of milliseconds so you only have one event, something like this:
import {Component, Renderer} from '@angular/core'
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/debounceTime';
@Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}}</h2>
</div>
`,
})
export class App {
name = 'Angular2';
subject = new Subject();
constructor(renderer: Renderer) {
renderer.listenGlobal('document', 'touchend', (e) => {
console.log('touchend');
this.subject.next(e);
});
renderer.listenGlobal('document', 'click', (e) => {
console.log('click');
this.subject.next(e);
});
this.subject.debounceTime(100).subscribe(event => {
console.log(event); //do stuff here
})
}
}
So when you use hybrid devices, you will get this:
Two events were fired, but you only get one on your Observable.
You can play around in this plunker
Just add (tap) directive instead of (click) directive on your components and add hammerjs to your index.html file.
Angular 2 will do all the job for you.
Example:
<my-component (tap)="doSomething()"></my-component>
On your index.html add:
<script src="hammer.min.js"></script>
To get hammerjs
npm install hammerjs --save
With this the click and the tap will work fine. If you want to have more control over the tap or you want to bind events to your element on runtime try something like this.
_hammerEvents: HammerManager;
public bindTapEvent(element: ElementRef):void{
this._hammerEvents = new Hammer(element.nativeElement);
this._hammerEvents.on("tap", (event:any) => { /* do something */});
}