I am trying to add a custom longPress event directive on elements, since (press)="callback_function()" will result in ion-list won't be able to scroll anymore. Bug or not, i've found out that I need to add a custom gesture directive that would add support for a new attribute, in this case I call it longPress. and it works great, except I don't get how to add the callback function :-)
I've followed a tutorial (http://roblouie.com/article/198/using-gestures-in-the-ionic-2-beta/)
The "press-directive" is created in src/components/press-directive/press-directive.js and looks like this:
import { Directive, ElementRef, OnInit, OnDestroy } from '@angular/core';
import { Gesture } from "ionic-angular/gestures/gesture";
/**
* Generated class for the PressDirective directive.
*
* See https://angular.io/docs/ts/latest/api/core/index/DirectiveMetadata-class.html
* for more info on Angular Directives.
*/
@Directive({
selector: '[longPress]' // Attribute selector
})
export class PressDirective implements OnInit, OnDestroy {
el: HTMLElement;
pressGesture: Gesture;
constructor(el: ElementRef) {
this.el = el.nativeElement;
}
public theCallback() {
}
ngOnInit() {
this.pressGesture = new Gesture(this.el);
this.pressGesture.listen();
// instead of this..
this.pressGesture.on('press', (event) => {
console.log('pressed!!');
});
// i want the callback to come from the template like this:
// <ion-col (longPress)="showActionSheet(object)">
}
ngOnDestroy() {
this.pressGesture.destroy();
}
}
In home.module.ts I have added the directive in an import:
import { PressDirective } from "../../components/press-directive/press-directive";
and I've added it in the declaration:
declarations: [
Home,
PressDirective
],
In home.html, I implement it in a like this:
<ion-col (longPress)="showActionSheet(relevantObject)">...
I've cut out most of the unimportant stuff :-)
And when I do a long press, it will return the following:
console.log('pressed!!');
But I can't get my head wrapped around how to support the actual callback function from the template element.
Any help or hint would be appreciated..
For anyone who still has this problem, I ran into a very similar thing, and Steen's answer was very helpful in figuring out adding a callback.
However, I wanted to add a little clarification, because I think the distinction between "press" and "release" (or "pressup") should be made.
According to HammerJS docs (which ionic uses for Gestures), there is a "press"
event, and also a "pressup"
event, which is fired when the press is released.
You can actually include an @Output
for each event (press
and pressup
):
/*
* The first output will emit when the timeout is reached for press,
* and the second will emit when the press gesture is released.
*/
@Output('long-press') onPress: EventEmitter<any> = new EventEmitter();
@Output('long-press-up') onPressUp: EventEmitter<any> = new EventEmitter();
Then, in the @ngOnInit
, respond to each event with each respective emitter:**
this.pressGesture.on('press', (event) => {
this.onPress.emit(event);
});
this.pressGesture.on('pressup', (event) => {
this.onPressUp.emit(event);
});
This way, you can support a separate callback function for each gesture event (in the template/component):
<ion-col (long-press)="longPressed(object)" (long-press-up)="longPressReleased(object)">
...
</ion-col>
Hopefully that adds some info/clarity.
Alright, so I was gently informed of the solution on the awesome ionic slack chat site (https://ionic-worldwide.slack.com) - I needed to use Output and EventEmitter
In the Import section, it had to look like this:
import { Directive, ElementRef, OnInit, OnDestroy, Output, EventEmitter } from '@angular/core';
import { Gesture } from "ionic-angular/gestures/gesture";
In the class, I had to add an @Output EventEmitter:
export class PressDirective implements OnInit, OnDestroy {
el: HTMLElement;
pressGesture: Gesture;
@Output('long-press') onPressRelease: EventEmitter<any> = new EventEmitter();
And the on('press',...) inside ngOnInit had to look like this:
this.pressGesture.on('press', (event) => {
this.onPressRelease.emit('released');
});
Now the template supports adding (long-press)="showActionSheet(object)"
:
<ion-col (long-press)="showActionSheet(object)">
And yes, I also changed it from longPress to long-press.. just looked better for me..
I was able to resolve this issue in Ionic v4 by providing HAMMER_GESTURE_CONFIG in app module. Follow this link for the solution: Vertical scroll is not working with HammerJS and Angular2