How do I know a pan-event has ended in nativescript-vue? - vue.js

The documentation of nativescript-vue provides little information on gestures. They can be used like so <Button #pan="handler" />, but how do I know, wether e.g. a pan event has ended?

The documentation on gestures is scattered, to date. But here is what I found: the event handler is passed an event object, as usual. This has a property called state which is a number to be interpreted using the GestureStateTypes enum. You can determine, wether the pan-event has ended like so:
import { GestureStateTypes } from 'tns-core-modules/ui/gestures';
export default {
methods: {
pan(event) {
if (event.state === GestureStateTypes.ended) {
console.log('Pan event has ended.');
}
},
},
}
These are all possible event states: began, cancelled, changed, ended.

Related

How to make preventDefault for change on Element UI radio group

I'm using Element UI radio button group and I want to use preventDefault() when trigering change event:
<el-radio-group #change="changeHandler" v-model="radio1">
<el-radio-button label="New York"></el-radio-button>
<el-radio-button label="Washington"></el-radio-button>
<el-radio-button label="Los Angeles"></el-radio-button>
<el-radio-button label="Chicago"></el-radio-button>
</el-radio-group>
Script:
methods: {
changeHandler(value, e) {
// e is undefined
// here should be preventDefault
}
}
I tried set second parameter to change function, but it is undefined.
Element UI works a bit differently. #change just returns the value chosen, nothing else. We need to use native to access the Event object. But #change.native won't work, as the change has already happened (if you want to actually prevent the change). As a side note, I would use disabled attribute instead (like presented in documentation). In my opinion for the UX it's weird that a user cannot choose a radio button, but putting that aside.... Use #click.native instead if you want to prevent a choice:
#click.native="changeHandler"
Then you have access to the Event object:
changeHandler(e) {
console.log(e.target.value)
if(e.target.value == "Washington") {
e.preventDefault();
}
}
CODEPEN
You're having the parameters in the method wrong. The are 2 ways this can go using the #change event handler:
A
defining a change handler without arguments, like
<el-radio-group #change="changeHandler" v-model="radio1" ></el-radio-group>
changeHandler(e) {
// e will be the Event object
console.log(e)
}
B
defining a change handler with arguments, put in $event to still include the event object
<el-radio-group #change="changeHandler($event, 'string')" v-model="radio1" ></el-radio-group>
changeHandler(e, value) {
// e will be the Event object
console.log(e);
// value will be 'string'
console.log(value);
}

Programatically assign handler for native event in Vue JS?

I am trying to leverage a Vue mixin to add behavior when a native event happens. Using a mixin will allow me to share that across several components. Specifically, when a field component (or button, or checkbox, etc.) has focus, and the Escape key is pressed, the field loses focus.
A similar Stack Overflow question seemed to indicate I could listen for native events (see code comment about multiple events).
However, the Vue Documentation for programmatically adding an event listener using $on says that it will
Listen for a custom event on the current vm...
(Emphasis added)
Unsure if the custom event remark is absolute or based on the context, I have been experimenting. I have been trying to listen for the native keyup event (using the Vue alias keyup.esc) but have had no success. So I am wondering if it is indeed limited to custom events, and if so, why?
You can see my experiment in a code sandbox. The custom event works, the native does not.
The mixin looks like so:
// escape.mixin.js
export default {
created() {
// Custom event
this.$on("custom-event", function() {
console.log("Custom event handled by mixin");
});
// Native event
this.$on(["keyup.esc", "click"], function() {
alert("Native event handled!");
});
}
};
The main point of all this is to be able to add the behavior to a set of components by adding to how the event is handled, without overriding behavior that might also exist on the component. The secondary goal is to provide the behavior by simply adding the mixin, and not having to do component level wiring of events.
So a component script would look something like this:
// VText component
import escapeMixin from "./escape.mixin";
export default {
name: "VText",
mixins: [escapeMixin],
methods: {
onFocus() {
console.log("Has Focus");
this.$emit("custom-event");
}
}
};
Also, I was trying to avoid attaching the listener to the <input> element directly with vanilla JS because the Vue documentation suggested that letting Vue handle this was a good idea:
[When using v-on...] When a ViewModel is destroyed, all event listeners are automatically removed. You don’t need to worry about cleaning it up yourself.
Solution
skirtle's solution in the comment below did the trick. You can see it working in a code sandbox.
Or here's the relevant mixin:
export default {
mounted() {
this.$el.addEventListener("keyup", escapeBlur);
},
beforeDestroy() {
this.$el.removeEventListener("keyup", escapeBlur);
}
};
function escapeBlur(e) {
if (e.keyCode === 27) {
e.target.blur();
console.log("Lost focus");
}
}

"nativeOn" vs. "on" in the render function & JSX

In the Vue documentation at https://v2.vuejs.org/v2/guide/render-function.html#The-Data-Object-In-Depth there is an explanation for “on” and “nativeOn”:
// Event handlers are nested under `on`, though
// modifiers such as in `v-on:keyup.enter` are not
// supported. You'll have to manually check the
// keyCode in the handler instead.
on: {
click: this.clickHandler
},
// For components only. Allows you to listen to
// native events, rather than events emitted from
// the component using `vm.$emit`.
nativeOn: {
click: this.nativeClickHandler
},
We are trying to listen to an “input” event from a custom component we created. We noticed that the event did not get detected in the on property, so we tried nativeOn and we were surprised to find that this worked. We were surprised because the docs say nativeOn:
Allows you to listen to
// native events, rather than events emitted from
// the component using vm.$emit
In this case, we are using an event emitted from a (custom) component using vm.$emit.
Here is a snippet from our code demonstrating the above:
on: {
input: (event) => {
console.log('hi'); // We did not receive "hi" in the console
}
},
nativeOn: {
input: (event) => {
console.log('hi2'); // We did receive "hi2" in the console
}
Any clarification on why we would need nativeOn to listen to “input” events from a custom component, or on when to use nativeOn vs. on and the differences therein would be most appreciated. Thanks in advance!

access methods from the vue current component

Can any one guide or suggest how to resolve this below issue.
Use Case: Trying to implement notification component
Scenario: I am trying to call a method or change the state of the data on triggering of event in Vue.
I have defined the event listener on mounted function and trying to access one of the method.
Basically, the alert within event function is getting triggered, where as alert inside method is not getting triggered, and even any data manipulation is not executing even with in event function.
Where am i missing? is it incorrect to alter state within Event listener?
Basically i am trying to implement notification feature which automatically disappear after few seconds
Any help is appreciated.
Thanks,
Girish
There is another reason,this inside callback function is not Vue component. You can assign var self = this and use inside the callback, or use arrow function.
mounted: function () {
var self = this
EventBus.$on('show', function () {
self.test()
self.show = true
})
},
methods: {
test () {
console.log('Inside methods')
}
}
I believe your problem is the spelling error instead of
method: {}
, use methods: {}
Example:
Error.
method: {
test: function () {
alert('Inside Method');
}
correct.
methods: {
test: function () {
alert('inside method);
}
}
I know it does not have much to do with the question, but be careful when using the event bus, it would be as if you had a speaker, and shouted in the middle of a crowd the name of a person.
Example:
eventbus says Hamilton in the midst of a crowd of 10,000 people.
How many Hamiltons can you have in the middle of this crowd? Use something more specific, such as parent-child communication, avoid using the event bus.

How to remove event listeners in Aurelia?

How to remove event listeners in Aurelia?
This doesn’t appear to do anything:
detached(){
window.removeEventListener('scroll', this.windowScroll);
}
The event is still firing when i change routes.
I am attaching it in the constructor() in my view-model file:
window.addEventListener('scroll', this.windowScroll.bind(this));
I also tried deactivate() and neither are firing when I change routes.
There is at least one, but maybe two issues here.
Setting up an event listener
If you can't use the Aurelia binding for event delegation (for which scroll may or may not be a case, I haven't tried it), then you should use the attached lifecycle callback to set up your event handlers, not the constructor. The reason being that, unless you specify your view model is transient, the constructor will be called once. Instead, you really want Aurelia to turn on your event handlers every time it is attached.
attached = () => {
window.addEventListener('scroll', this.onScroll);
}
How to write a lifecycle callback
In general you should write your lifecycle callbacks using the arrow notation. This is because, IIRC, your this may get reassigned during the activation lifecycle. The arrow notation in TypeScript/ES6 will preserve your this lexically, i.e., it is what you expect it to be.
detached = () => {
window.removeEventListener('scroll', this.onScroll);
}
It's worth noting that you need to define your bindable function up in the constructor if you want to unbind it again on detach:
export MyClass {
constructor() {
this.handleBodyClick = e => {
console.log(e.target);
};
}
attached() {
document.addEventListener('click', this.handleBodyClick);
}
detached() {
document.removeEventListener('click', this.handleBodyClick);
}
Taken directly from this excellent post: http://ilikekillnerds.com/2016/02/using-event-listeners-in-aurelia/