[v1] Events context (acessing the component itself inside @event handler)
-
How do I get access to the component itself inside an event handler?
<q-input ref="inp1" @input="myGenericHandler" myAttr="123"> <q-input ref="inp2" @input="myGenericHandler" myAttr="456">
{ methods: { myGenericHandler(value){ let comp_ref = ??; // How to access the Quasar/Vue component from here?? let comp_myAttr = ??// How to access the DOM el from here??? } } }
Thanks
-
@labs20 -
this.$refs
maybe? Not sure what you mean or need to do to be honest.https://codepen.io/smolinari/pen/darPMb
Scott
-
Hi. Thanks for the answer.
Imagine you have a dynamic form with components that are all created at “runtime”. In this scenario you do not know in advance which, or how, or how many components there will be at a given time, as they will obey to some random “fields” arrived from server.
So your event handlers must be generic and pointed to a bunch of components. For example, you would have one event handler called “onDateChange” and assign it to every QDate input instance that might be created, and inside this handler you might need to know to which “field” that instance of QDate was dynamically created for (say, field dt_start or field dt_finish…)
This is why I need to access the emitter of the event inside the handler.
Hope it got clear
Thanks in advance.
-
I still don’t understand what the event handlers need to be doing. You can catch an event with
@keyup
. It’d be basically the same as if you’d catch the@input
event.https://codepen.io/smolinari/pen/darPMb
Scott
-
He needs event.target like native js events
-
And it is there. It returns
<input aria-label="Enter something" type="text" class="q-field__native">
.It might be I am being a bit dense here from lack of experience. But, if you could explain what it is you want to do with the event, I might be able to help further anyway.
Scott
-
And if I add the attribute, like in the example above I get:
<input myattr="123" aria-label="Enter something" type="text" class="q-field__native">
But, that is still not necessary as you have the refs and you can also get the attributes and the component (also dynamically) with the refs.
https://codepen.io/smolinari/pen/MLxrdL
Edit: Not sure where the warning is coming from. I think we can ignore it for now.
Scott
-
@s-molinari Thanks for your effort to understand and to provide a solution. I appreciate that you designed a valid option on your codepen, but still doesn’t quite fit my needs.
In a nutshell, I need to be able to access the emitter (or target as pointed by @lucasfernog) inside the event handler.
I think that is just natural that some reference to the emitter should be available on the handler and there are dozens of cases that you would want to access them.
In quasar, many event handlers have an specific signature that will be broken if I just call it passing my own parameters like
index
on your example.Take this QSelect
@remove -> function(details)
for example:{ methods: { defaultOnRemove(details){ // details are fine and preserved here // but who is the emitter??? } genericOnRemove(index){ // Ok, I can use the index here to find out the emitter // but where is details??? } } }
Please note that more than an alternative or strategy (that may work on some specific scenario) I think that the emitter should “just be there”.
Thanks again.
-
An suggestion that would not break any code, is that all quasar events got a last
emitter
orsender
parameter. This would close the case and no functions would be harmed on this movie footages. -
Couldn’t you use a different event, like I did earlier with “keyup”? That wouldn’t mess with anything from Quasar.
https://codepen.io/smolinari/pen/MLxrdL
I highly doubt Quasar will be adding any other arguments. That is what the $refs in Vue are for. They are basically the “interaction bridge” between your HTML code and your JavaScript.
Also, and actually more important, you can create your own custom select or input components, where your event catching methods are part of the component. Then you only need to generate your custom components dynamically and they’ll all have their own scope. So, there is no need to know who the emitter is. There is only the one input field per component.
Scott
-
@s-molinari said in [v1] Events context (acessing the component itself inside @event handler):
Couldn’t you use a different event, like I did earlier with “keyup”? That wouldn’t mess with anything from Quasar.
But, how I’ll do that when it comes to events of the likes of
@remove
or the ones that are mouse/tap related?I think the point is missed. In my point of view it’s a design mistake to not be able to know the emitter of an event when inside the event handler.
Sure will be many workarounds to deal with this (IMHO) flaw, and looks that I’ll be needing to using some to go trough, but the problem remains.
Please I’m not meant to be rude, but two handlers just to achieve something doesn’t seems “right” to me.
I highly doubt Quasar will be adding any other arguments.
Well, I’m ok with that. Adding it as a last param seems to be a pretty harmless and easy thing, but then again, its not me that are doing this giant (and great) work of yours.
Its a shame, but… workarounds to rescue.
Thanks for your kindness.
-
Please try the custom component method. Don’t rely on Quasar’s components to build with, but rather build your own, adding the logic you want within that component. If you do that, you shouldn’t need the “generic” event handler as the event handling is local to the component. There is then no need to decipher which component triggered an event to then know what actions to take. I hope that makes sense.
Scott
-
Thank you, Scott, I’ll try that way. Can you point me some good doc/references about extending quasar comps?
-
I did earlier with my component building article.
Vue components are simply composed together. Just as an example. You wouldn’t want to have to build the QSelect out as a filtered select field and also build out an autocomplete search field within a form, should that form need those two types of fields. Or, maybe you also want to have a select field, which has check boxes to show the selection has been made and you need a number of these select fields in your form. You’d want to first build these select fields as your own custom select components, so they do these single things (and maybe build on top of those for your styling! We can argue about that, if it is needed, since Vue components splits HTML, JS and CSS internally in the component.). Once your custom components are built, you just “import” them into your form and use them. The only logic you should at that point be concerned about is the form logic. Nothing else. And, if you build new forms in the future, your custom components are ready and waiting (and finished) to be consumed.
Oh, and in the future (actually you can do it now, but we’re not finished with the API yet), if you came up with some sort of really cool select component, you will be able share it as a Quasar App Extension, so other devs in the world can use it too. More on that later.
Scott
-
Quasar App Extension
Thats sounds great.
Thank you