Skip to content

Capture Based Eventing#86

Closed
runspired wants to merge 0 commit intoemberjs:masterfrom
runspired:master
Closed

Capture Based Eventing#86
runspired wants to merge 0 commit intoemberjs:masterfrom
runspired:master

Conversation

@runspired
Copy link
Contributor

@greyhwndz
Copy link

This is definitely among the important areas where performance could be addressed especially development in mobile.

@pixelhandler
Copy link

@runspired how do you see this RFC relating to "universal event dispatch" http://emberjs.com/blog/2016/01/23/core-team-face-to-face-january-2016.html#toc_universal-event-dispatch

This RFC proposes moving Ember to an event model based on handling events at the very beginning of the capture phase, and delegating them to the correct handlers ourselves.

I'm a fan of event delegation and the ideas mentioned in the "universal event dispatch" resonate well with me. So I'm curious if you think the "Capture based eventing" could be expanded to become part of the story around 'universal event dispatch' …

when the user interacts with a component, we rely on the fact that the DOM event will eventually bubble up to the document, and thus and the event handler Ember has installed

I'm curious if 'capture' is compatible with the ideas around delegation which require bubbling.

@runspired
Copy link
Contributor Author

It's compatible, and definitely related. The core concerns are that any event management system needs to

  • smartly attach/detach listeners based on what's currently needed
  • balance memory overhead with delegation speed
  • have a delegation speed that's at least within a non 10x multiple of onclick, probably faster
  • thrive in the most hostile of CPU environments
  • support 3rd party

I think capture is the only way to achieve the middle 3 of these, and that any other solution will ultimately lead users to hack around the event system, or abandon Ember for something else if they no longer can.

@runspired
Copy link
Contributor Author

I updated the RFC to reflect the general direction and concepts that have evolved from the original proposal over the past few months, as well as to (hopefully) make it an easier read.

This led to a great discussion with @mixonic which centered around what to do with the following case:

<my-wc ongroan={{action 'frump'}}>

my-wc is a custom WebComponent, not an Ember component, (but it could just as easily be a Glimmer Component, the challenge is the same).

In the proposal, Components define an events hash in order to explicitly separate event handlers from other methods, but the template API has no such ability at the moment.

This was apparently the intent behind #112 (reflected below).

<my-wc {{add-event-listener 'groan' (action 'frump')}}>

@mixonic floated the idea of adding an {{on helper.

<my-wc {{on 'groan' (action 'frump')}}>

Which would enable this to work for 3rd party libs or for glimmer components. I like this idea, but am still thinking it over. The discussion then evolved into a more metaphysical discussion of the differences between actions and events.

It seems to me the main problem currently being discussed by core is that the ergonomics of actions and events are clumsy. There are two separate paradigms for things that are essentially events, and neither paradigm currently plays well with 3rd party components, which is quickly becoming a necessity in modern web apps.

So the questions become:

  • do we turn actions into events ?
    • if so: events hash only?
    • if so: actions hash only?

The ergonomics of adding listeners in templates. What is the right way to declare event listeners in templates?

  • {{action "foo" on="bar"}} is inelegant (and works poorly for events at the moment)
  • {{on 'bar' (action "foo")}} is a potential, but also expands an already verbose set of template helpers
  • {{add-event-listener 'bar' (action "foo")}} at least is relying on an existing element API, but is a pain to type out
  • onbar={{action 'foo'}} is problematic because it's difficult to know that this represents adding an event listener. It could just as easily be a property being passed to the component. Additionally, for WebComponents we don't know if the component will have implemented use of onbar, and because it's not wrapped in quotes currently it technically should not be reflected onto the element as an inline listener.

Another problem (if unifying events and actions), methods within the events hash are supposed to become listeners for that component, where actions are usually events listened for somewhere within the component's template.

This suggests to me that there needs to remain separate hashes for events and actions, differentiating between handlers that are there to be attached elsewhere, and handlers intended to be attached to the component itself.

If we accept this mental direction that "actions are for defining event handlers that can be utilized elsewhere", then I think we come back to the on helper. I'm not certain I see a path that is explicit, universal, and does not introduce a new helper.

It's probably too hard to work over the existing syntax, especially if actions themselves are an event delivery mechanism. The existing system only uses events when no params are specified, not all the time.

Existing patterns

<div {{action "foo" ...params on="bar"}}>
<div onclick={{action "foo" ...params}}>
<div {{action "foo" ...params}}>
<div {{action foo ...params}}>

Potential New Syntax 1

<div {{action 'bar' "foo" ...params}}> 
<div {{action 'bar' actions.foo ...params}}> 
<div {{action 'bar' attrs.foo ...params}}> 

In syntax 1, we repurpose the keyword action to indicate the addition of an event handler, and the first argument becomes the name of the event to listen to. Unfortunately, this is likely going to be problematic to handle deprecations for.

Potential New Syntax 2

<div {{on 'bar' "foo" ...params}}> 
<div {{on 'bar' actions.foo ...params}}> 
<div {{on 'bar' attrs.foo ...params}}> 

The "trouble" with new syntax 2 (and syntax 1) is that there's a lot going on with these params, you basically just have a long list that may have little contextual meaning to a new developer.

Potential New Syntax 3

<div {{on 'bar' (action "foo" ...params)}}> 
<div {{on 'bar' (action actions.foo ...params)}}> 
<div {{on 'bar' (action attrs.foo ...params)}}> 

For some reason this just feels cleaner in some ways than a long list of things following 'bar', but it also requires the use of two keywords, one of which would have deprecations to deal with.

Just some thoughts I wanted to jot down for posterity, have a different direction I'm considering that I feel may be better but I need to let it settle out a bit.

kategengler pushed a commit that referenced this pull request Jan 19, 2019
Replace PhantomJS with Firefox
@runspired runspired closed this Apr 24, 2021
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

Successfully merging this pull request may close these issues.

3 participants