I'm trying to bind a (tap) event on a custom Angular component in nativescript.
I created a custom component called 'ns-custom' and tried to bind the (tap) event to it. But it doesn't work.
In the custom component I'm doing this:
<StackLayout>
<Label text="Title"></Label>
<Label text="some text"></Label>
</StackLayout>
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'ns-custom',
templateUrl: './custom.component.html',
styleUrls: ['./custom.component.css']
})
export class CustomComponent{
constructor() { }
}
And in the parent element I'm doing this:
<ns-custom (tap)="onCustomComponentClick()"></ns-custom>
onCustomComponentClick() {
console.log('custom-component was tapped');
}
I expect the (tap) event to fire when I tap the custom component, but it does not. I built the same structure in pure Angular, and the (click) event does fire if put to a custom component.
I tried to propogate the (tap) event from the custom component like below, but then it fired twice (as expected because the tap event would propogate up to the parent component if I don't use event.stopPropagation()):
<StackLayout (tap)="emitTap()">
<Label text="Title"></Label>
<Label text="some text"></Label>
</StackLayout>
@Component({
selector: 'ns-custom',
templateUrl: './custom.component.html',
styleUrls: ['./custom.component.css']
})
export class CustomComponent{
@Output() tap = new EventEmitter();
emitTap() {
this.tap.emit();
}
}
And then catch the event on the parent component:
<ns-custom (tap)="onCustomComponentClick()"></ns-custom>
onCustomComponentClick() {
console.log('custom-component was tapped');
}
But now the tap event fires twice. I can solve it by changing the EventEmitter name to something other than 'tap' (for ex. @Output() childTapped = new EventEmitter(); and <ns-custom (childTapped)="onCustomComponentClick()"></ns-custom>) or pass the $event object on tap and then use event.stopPropagation(), but this is not elegant at all.
Any idea how to solve this simple problem in an elegant way?
(tap)binding. The way to solve this is by binding(tap)on the custom child component, and then emit an event with an @Output decorator named something else other thantap(saytap_) so that the event propagation has this logic: custom component listens totapand then emits a different eventtap_to its parent, that listens totap_events. This way only the custom component'stapevent is picked by angular and is fired only once@Output() tap_ = new EventEmitter();, and a functionemitTap() { this.tap_.emit(); }. In the html, bind this function to the tap event on the element:(tap)="emitTap(). Then, in the parent element, set an event listener on thetap_event:(tap_)="doSomethingByParent()", and write the code you need in parent'sdoSomethingByParent() { // ... }. You can pass angular's$eventbetween those events if needed.