Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: can I attach event to element, not to window? #71

Closed
new-user-name opened this issue Apr 5, 2023 · 12 comments
Closed

Question: can I attach event to element, not to window? #71

new-user-name opened this issue Apr 5, 2023 · 12 comments

Comments

@new-user-name
Copy link

It's convenient when you have multiple dialogs on the page.
Thank you!

@new-user-name
Copy link
Author

Consider this: you have many file-upload-with-previews on the same page. They were inserted from the same Vue component multiple times. Each one of them has

window.addEventListener(Events.IMAGE_ADDED, imageAdded)

You end up with n listeners and all fire.

@johndatserakis
Copy link
Owner

johndatserakis commented Apr 8, 2023

Thanks for the message. Personally, I think the way it is setup makes sense in the current iteration.

Unless I'm missing something - you don't need n number of listeners, you just need the number of listeners you're interested in, Events.IMAGE_ADDED and Events.IMAGE_DELETED for example.

Then, when filtering the event, you just look for the detail.uniqueId you're interested in.

window.addEventListener(Events.IMAGE_ADDED, (e: Event) => {
  const { detail } = e as unknown as ImageAddedEvent;

  if (detail.uniqueId === 'myFirstId') {
    // ...your code
  }
});

What's your opinion on this? Is it ok for your usage?

@new-user-name
Copy link
Author

new-user-name commented Apr 14, 2023

I have the root Vue component and numerous children set in a loop, each containing file-upload. So where do I have to add eventListener? If I do it in the parent component, I must pass a lambda to a child (God knows why it frightens me). If I add eventListener in a child, I end up with multiple listeners.

Right now, I add eventListener in a child, change a tag somewhere in a root div ('events = true'), and other children check whether the tag is set and do not add their listeners. So I have one listener, and this listener checks uniqueId, as you pointed out.

@johndatserakis
Copy link
Owner

The event listener is attached directly to the window, no need to enter the loop, or provide further lamdas. Then, you can maybe use a switch on the uniqueId that comes through.

Sorry if I'm not fully understanding your use-case. If you could provide some sample code I'd be willing to think through this further. But I think what I've shared should work, unless I'm missing something fundamental with the Vue implementation.

@new-user-name
Copy link
Author

My question "where do I have to add eventListener" means not "to what object I have to attach eventListener", but "in what point in my program I have to put window.addEventListener(Events.IMAGE_ADDED, imageAdded)".

The skeleton of Vue component looks like

Parent
	Ten children, all the same

If I add eventlistener in children, I have 10 eventListeners attached to window. If I add eventListener in Parent, I end up with
window.addEventListener(Events.IMAGE_ADDED, imageAdded)
where imageAdded is currently in child. I don't know how address function in child component from parent.

@johndatserakis
Copy link
Owner

johndatserakis commented May 2, 2023

Understood.

In the case of a Vue app, because this event is directly on the window, you don't need either option actually.

What you need is this I think (for a Vue2 app):

...
created: function() {
  window.addEventListener(Events.IMAGE_ADDED, this.yourHandlerFunctionHere);
},
destroyed: function() {
  window.removeEventListener(Events.IMAGE_ADDED, this.yourHandlerFunctionHere);
}
...

More info here. But this is how I would approach it.

@new-user-name
Copy link
Author

new-user-name commented May 4, 2023

Where I have to do it, in the parent or in the child?..

@johndatserakis
Copy link
Owner

If it's like 10 children (not 100+) I think it's fine to add it in the child and have multiple handlers attached to the window. Then each child check that its own uniqueId is the one in the event before acting.

Another way is to setup the handler in the parent, and pass down the needed result to the children as a prop.

There probably is other ways to handle this if you search around a bit.

@new-user-name
Copy link
Author

Yep. There is something in me that repels the idea of 10 listeners, but maybe it's the same thing as checking html attribute as I do now.

The second option I see like this: in parent component IMAGE_ADDED event sets array value, for example [0, 0, 1, 0, 0], array values are fed down to child components by corresponding numbers (6th component receives 1 when image uploaded to 6th, other receive zeroes), and watchers inside child components monitor their input props.

All these are feasible... More or less... Clumsy but feasible...

@johndatserakis
Copy link
Owner

Yea you got it, sorry it's not ideal. I will continue to keep this in mind going forward.

@new-user-name
Copy link
Author

Sorry John, I did not have intention to be disgruntled. Your module works just fine inside user-generated tool within Laravel Nova. No tuning needed. It's good as it is.

@johndatserakis
Copy link
Owner

No problem at all, glad to hear it. Closing for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants