name is Marie Chatfield you might also known years at Marie Chatfield on Twitter area get slack all the places and I am inundated you on learning during all about events and so I'm a softer engineer it's where were we meet commerce easy you Minister hardware elected taking on go on we anywhere we also have a developer platform with the guys in acid cases and got the time of software that helps merchants run their businesses really easily things like appointments and invoices is the role and the surgery of all of that software lives and this is not in the out that we call a ESPRIT dashboard and it's a I and a lot of other in the developers it's square spend a lot of our time so a

01:03

couple months ago I was working with my team and not massive apps you add a new feature and so the idea was that we have a button that you can click it would open a menu you can click it again and then you goes away which is you know I'm really groundbreaking stuff here so we decided to ensure uses a little bit of extra information the 1st time they saw the feature those kind of new so we decided to have a walk-through to so this time the 1st time he sort of feature we would give them this popover with some information it had a button that they could collect it would advance toward by opening the menu for them and then giving them a little information about what they could find it so the women we implemented was we had a tool to

01:47

get an inside of that was button that we were actually have users click in order to advance the toward and then that was actually inside of the button that we wanted people to click to open up new and shut so I mean what very small code change and everything work so let's go ahead and take a look at the code change that ruined my life that's it has only been a change so let's see what happens now

02:21

the user clicks on the button to advance the Torah menu opened this and then the menu chefs which is

02:30

not what I expected to happen so this kid doubt about 72 hours of need debugging badly I mean I was looking at stack traces I was really source code I was making between old I was doing flow charts like on paper I like I was trying to figure out what in the world was going on in the result of all of that investigation and research was that I realized that

02:54

before I had been exclusively listening for events with and the and after I was missing events for the combination of Amber and the need of down at what point maybe the thing you might wait hang

03:05

on what is the difference between those 2 things and how did that code change have such a big implications so look back

03:14

at all the way out so what is the down in the 1st place it's document object model and it's basically made yeah the describes how web pages work so browsers implemented on that in order to actually turn just start each team now

03:27

in a file to this will the web page you can interact with and this is really important data structure here that we call the DOM tree in its this hierarchical the a structure and everything in your web page can be represented as and when it's somewhere in the streets starting with the top of a document and all the way down to every single day button It's a node in the street we also have a concept of events in the down

03:49

this is an a it describes basically that something happened on the cage so usually this is the result of some user interaction might or a keypress or attachment on mobile and the don events in Qinghai gives us a way to have nodes do something when an event is triggered on them for example we can say that when a user clicks this button I went to the locker low to the Council and so 1 of the easiest ways of doing this is to use the on event actually it's NTHU she not where we just say for example 1 click equals and then we just write JavaScript and that a string and then when ever the button is clicked then not JavaScript inside a string is going to run around but maybe if during some more complicated things we don't wanna write of adjusting the set strain directly in line with so we can also do things like say give up at 90 and then somewhere else in the file used other a totally regular don that come out of the box to finite element in an adequate was so that brings us to the back-propagation this is a really important concept in the dock which is that every single parent of a node that had been on it also has a chance to respond to that same at that and this is the sort of default behavior that happens so if we have out here and a child node in the fact that listeners if we click that child node 1st it's it was there will fire and its carrots and why we do this kind of makes sense reading about saying we have a button and the button has I continents and text cited if the user manages to click exactly on the icon we probably still want the button to fire but we don't have to add that listeners to the button to the text to the icon in the notes inside of it and then there are some cases when we don't want this to happen we can always calls shock propagation on our in which case when we click on that child node it's event was a woman vinyl stock propagation and nothing else fires about it so all that

05:55

has been just regular down was is the 1 about anger and it was summer's so this is an abstraction that Member provides on top of DOS dominant listeners pretty heady it works a lot with the way that we can expect a wraps ago so if we take my regular dominant listener we can make this and that was by using our action to help the and specifically this is going to be in some kind of hours while and then the corresponding component of control are going to define an action we we actually use state so of like Franconia string there we can do that out this you we have access to that on that anymore so how do we stop propagation well in Peru provides instructions for that too we can just say bubbles equals lost and I'll stop propagation force with a and that listeners so now

06:45

we have this concept of dominant listeners and and remind listeners cut is actually get together in our application while women and that is traded in your at 1st all of the dominant recessive going to fire and then the emperor that listeners so when we're looking at these dominant listeners were gonna start at the target node wherever that event 1st originated we're going cycle to all of its kind and every step the way we going to see if there's a dominant was fire at if any of the staff propositional immediately exit and don't continue but if we make it all the way through our documentary will start all the way back over at that original down them cycle all the way back up through all the parents this I'm looking for Endre that listeners find and once again if any of them some propagation will immediately accepted so the important thing to realize here is that we were working with the dominant listeners it's actually the browser that is handling all of that event was the sea and calling a similar using argon itchy eyes and when we're working with art in the events is actually emerging as source code that it can the state of all of those event listeners and actually calling so how is that actually fit together so when you render content in

07:58

in the application you're probably thinking of the actual things that you're writing a your templates but all of that is actually rendered inside this route elements so this is a node that itself initializes when its 1st meeting of your application for the 1st time and there is isn't selling down that listeners on that node it's going to kick off its own internal process so getting a warning we're about to die so pretty deep into the internals of inverse source code in order to figure out how this works so that is something that you really don't care about the real now for the next 5 minutes checked Twitter do whatever and I will let you know when Mr. Weitz's sting back up to reasonable doubt and continue on the rest of the talk so for those of you that are paying attention this is great file and the inverse source can cultivate dispatches and it has this list of all of these different events that Member cares about and when the after initializing we call this function call that appeared on the root element with each 1 of those that's so let's say we're calling set up handler with the click event or going to do is we're actually going to add japery that listeners on the root element for those click events and these handlers are going to actually dispatched to the Embraer that listeners ward different elements and I know some of you are probably thinking this pointing on decree that listeners about the tree was optional yes it is optional the trying to get the branch of the of categories you agree in if you don't do this other stuff on 1 side is a little tricky so just trust me that the 1 without tinkering does pretty much the same thing it's a simpler to look at the G. agree example energy for example or others this extreme argument it's past that I hadn't seen before which is a CSS selector does little weird and to just using japery event handlers just past the single thing so let's take a look at that function signature what we're doing is we're passing on and then we went attach a CSS selector and then we had the fraction so normally integrate when you are adding a handler function to a node it's interact event handler and so the idea is when an event happens on that node you call the handler at 1 time but in this case we're working with the delegated event handler so we also have a CSS selected were passing so we capture him some node somewhere in the and then when an event happens on 1 of the children of that node that it's going to properly all the way up to the node where Hendler was installed at which point where color hindley function directly instead we're going to find every single child in that class that matches the CSS selector in a minor car him with function once for each of those which is pretty cool delegated so the lagoon art example we can see

10:54

that we're attaching a clicker listener to the root element we have this interview class that were going to be looking for that's a class that is added on every single component when it's when you into the Don and we had this can only function is going to handle plates on components so we attach this handle component click listener to every element when application is 1st initialized and then when a button somewhere inside of our application is clicked eventually that vendors have probably all the way up to every element at which point we're going to find every single elements and in that time that has this and would you class on it and they were going to call handler on each of those events in this event handler is going to say I'm looking at a component does this component have the clicker that listeners the and the if it does go ahead and call that some propagation do whatever and then just you do not for every single other component in the path between the target that when you read the event originated and route element and then the

11:55

really cool thing about delegated event handlers is that they you can use the same handlers of the entire life cycle of your no matter what country you're adding and removing from the dawn inside and out because the actual path of elements the your calling a handle on is calculated when the event happens and not when you install the handler so you can reuse the exact same handlers of the entire life cycle of your app without adding any new ones so you zoning out feel free to come back to that were sort of servicing that debt to like a normal level of depth and take a look at what happens when we actually put something in application so say we have our child node and turn on and we actually go ahead and hand about the 1st thing we're going to do is the browser is going to look for any needed and that listeners on that child and call them propagate up to the parents would bring down that listeners there and call them propagate only up to Harvard elements where it is going to find the delegated that listeners that and were applications solvent was initialized and copper and events process so now we're going to go straight back down to that type of node look for analysis and call them property that's you the parrot look for and prevent listeners and call those so the really important information here is that are dominant listeners are always called before Embraer that listeners which means a your environment was there and never going to be able to stop propagation to dominant listeners the

13:26

paper so it seemed like the difference between that listeners and down listeners is pretty important but how do you know which 1 is which 1 actually adding that listeners in my act so

13:39

so take a look at some different ways you can attach that listeners and probably the most straightforward way of adding a native of dominant was there is to just add 1 yourself somewhere in the life cycle of your application using J. query using regular adopted as this 1 looks like any dollar that was there so it kind makes sense editors is the most likely will by an ad dominant you're out you're going to use that on event equals a syntax in each to now this is confusing because noticed that that in the template helper is showing up here is a creating a closure action when you're actually doing is wrapping all of the in receive available in that context into a pure JavaScript function passing back off to be done in the down just going to handle it normally now this is extra confusing because you can create word that listeners by just getting rid of that an people syntax what you're doing here is using this element modifier syntax we just dropping that action template Holberg in the middle of a dog and tags and that's what him the wasn't going you'd actually add and that listeners using and that was 1st and the same is true if you just right it's type of event you looking for by default it's click that you could do anyone that's so when and where that listener if you passed the function to component that has a special name like click or keypress that not so 1 of dominance cares about you're going to create a member of that was there and the same is true if you do not you draw the script and sent it in your template and role and where the listeners so

15:15

now we understand some of the difference between that listeners and dominant listeners let's if you go back to my original by the code sample and think about what went wrong so we can

15:26

see once again that we have that in child action that is going to advance toward by sort of opening the menu at the sort of propagation and then we have our carry action that is going to actually follow them in you so when we click on this in a button the 1st action of the virus is the parent it is acting down event was so that is what is going to open and then you and then we get down to action that is going to advance the tour by closing the menu and that's going to some properties of the signals from wire after that so 1 of the easiest ways to fix excess just to make Perelman into an that was the in which case they're going to fire in order that we expect so the 1st thing they will find this case is child action it's going to advance the toward and it does successfully stopped crack addiction so everything

16:17

works right right it's not is actually a lot of other tricky situations that you can get into when you mixing and that listeners and dominant listeners so we're gonna don't plot i it's a bigger

16:32

ready for time to test your knowledge with wondrous and different tricky scenarios and see if you can figure out what that ideas have it so the first one I stopped propagation with my was there but the parent is still fire on this on this case we have this action that should not be firing and insight that we have an action that's going to stop propagation right so when we click on that innermost component the 1st use when a fire this impact that child of that was because of a dominant was unfortunately it's a dominant was there and we try to stop propagation using an Anbar abstraction you're in the abstractions are meaningless to the darn it does not care it is not really stop propagation that and it's still going to fire so we have a couple different ways of fixing this we could just make this into an amber action so because this these are both in reactions they are going to fire in order to expected and so the 1st thing thinner fire is the 1 where the click actually happened that does suck propagation this works alternatively we could go all in on a dominant listeners so in this case what we can do is actually start propagation within our functions were gonna have access to that original dominant in the skull stop propagation on there so once again not in a child's action is going to be called 1st because it is a dominant it's when to successfully stopped propagation in the parent will be fired OK so this case 1 of my that listener is being of but the event object is undefined kind of hard to stop propagation on something undefined so this case Hendler is just line out all the arguments that gets so it's 1st attach it using a element modifier syntax this is an M in was a right so when we put on this action we nothing no dominant on the so if you are using this element modifier syntax and U.S. out propagation or prevent default you have to use the in the abstractions you do not get access to that original done that OK but what if I pass said as the click function to a component what I did you do have access to the original down and then when you are passing things to a component using 1 of especially and click handlers the key press or whatever which is cool but hang on whatever our past some extra state in my action like you know do something else at my closure actions to a sum of access to the this is appended to the list of all the other arguments the path Elizabeth City look back at all of those different examples that we had about how to attach we can see that every single 1 of them except the element modifier syntax does have access to that original down event and it can to do things with that such time important to know

19:37

OK so with me so they're hanging in north after lunch I have another but example for you and this 1 is a doozy I and was

19:48

the It's not firing no matter how many times I clicked it and I clicked it a lot we set out with the carrot action that we expect them to not be fired inside and that is an actor that's going to stop propagation and inside and that is something which is going to say hello so we expect that if we click on that most a action we were going to say a whole right unfortunately the 1st thing that fires is our down the middle which stops propagation so we don't do anything else at this point including saying hello so we can't just make this into an embryo that was there to in which case actions will fire in the ordered we expect so if we click on that and was button once again we're going to say hello and then we're going to stop application if that were not actually has some we because we were expecting to get a dumb that objects that's the many undefined his freezing on modifier syntax so that the action is going to fire so we really want this to work as expected we're going to have to use part and were abstractions as a bubbles sepals falls in order to correct some propagation so that we say hello and then actually handle the click and some propagation the way that we expected so the takeaway here is pick 1 event listener strategy and stick with that really care which 1 you get I think they both have pros and cons as so for example when I am working in the sort of massive moderate though of that I use at work a lot of times you prefer to use it was just because I know that if I stopped propagation it's less likely to wreak havoc if other people are using what other kinds of that listeners of using no my personal projects and tend to prefer to use dominant listeners because I find the closure actions are just a lot often used intact I like the way that they look and I just find them a lot easier to work with so does it really matter which 1 you pick is always you just pick 1 so if you have

21:47

to pick 1 I'm sure some of you are wondering what performance if I just had to pick 1 sanity I want the 1 of the fastest most performant than it might happen newly snappy so as you do collect and

21:58

I tried adding up to 10 thousand components on a page at a time with each of the components but using a different kind of clicked listener once with the dominant once without modifiable theories and once that component listeners and I did some very unscientific profiling in Google Chrome enacted frozen just you know take with a grain of salt but this is more of a high level picture so

22:23

as you might expect when you are using dominant listeners for every 1 of your components if you add thousand components to a page you add 2000 dominant listeners to the page but if you're using a word that listeners which use the same and that listeners from the app to delegate out to listeners you actually is only about 30 to in order to render 2000 opponents so that's a lot less and their listeners in the dumb but if it dialect keeping track of that state surely always keeping track of that state's or my using more memory yes you are you are using my memory

22:59

it's honestly I would consider it off will bring this amount more memory for the browser to handle and it's kind of a trade off here but you are using more memory when using that was 1st but

23:12

what about speed and that listeners are delegated to cite new gonna take longer for my that listeners to fire

23:19

no they ran out the same you know we don't have to worry about the speed for the Villasenor's actually fired OK so want the strategies more performance it's kind of like to tell you the spinning so don't get into that listeners were added at a time when adding a bunch of dominant listeners to the down day caused serious performance problems that's why delegated atlases came into popularity now most modern browsers can actually handle that number of dominant listeners out if they can probably also handle that extra memory overload so I would say that there's not really a clear winner in my mind these some performance in most modern browsers about really you have the information that you need in order to make a the decision for your app and honestly I would say that you should probably pick the that was the strategy that's going to help you write the most clear correct and consistent code I just had seen herself pain when you're debugging

24:12

OK a feature requests this kind of interesting if you wanna actually add a

24:20

listener so let's say we have some element and it's got an active state in an inactive state and was actively wanna have had to be what of the game and when it's not you don't so how do you do this another perfect and beautiful world it is say something like it's active and I want to add this and they handler but but you can't do that you get a compiler error you can use the if statement in that element modifier syntax like that so how did this well I'm your best option is to just use semantic HTML don't try to reinvent the wheel we have things like buttons that you can do and you can pass the disabled state and then the browser will take care of making sure that those events are actually fired into in showing you the correct disabled state that's really what you're trying to do is reinventing stable silent on a if for some reason you really can't use semantic what you could do is just let everything into separate if blocks and have very clear exactly what you're doing interview different states and that that can get a little redundant you can just eggs it early from your Hendler if you're not active so you always attaches it you just don't do anything if you exposed to you can't just use a government listeners and because you aren't using that we've seen in and an element of our syntax in this case we're actually doing is you're actually passing and function to the dumb and dumber secure that's all that's holy valid and of ours so that is a little bit easier to use than event that was there's just a

25:58

quick word of warning here this is actually what I was doing when I concept but that started this entire presentation so if you are using that listeners alter in your app and you're trying to actually and it wasn't just be careful if you cited as such it up and use a dominant with they're just this 1 case so really going take away here that I want all

26:18

of you to remember is that down that listeners always always always fire before inbred that listeners there are no exceptions this always happens and the 2nd thing is that I really want you to remember the consistency and predictability of still important when you're handling events in your application this is really what is going to save you a lot of pain when you're implementing and dividing things so I hope that this point that

26:43

all of you have all the knowledge that you need in order to implement your at that listeners with confidence and debug clarity as you

26:51

had in the back on the soccer in unit questions once again I'm at Marie Chuck on Twitter you can find links to the slides for this talk every chapter that come such talks and if you're interested in reading the original blog posts that I wrote after that 72 hour dive into amber events that eventually turned in those talk given by not on this work on a blog on Medium thank you so much for your time this to that end you you

Inhaltliche Metadaten

Advance your Ember events knowledge from entry-level to expert in 30 minutes! Start with the basics of DOM events, learn the lifecycle of event listeners in Ember, then peek under the hood to understand how Ember handles clicks in your application. What are the different ways of listening for events in Ember? How do they interact? What are the performance implications of each approach? What kind of bugs can you introduce if you don't understand them? You'll be able to implement event listeners with confidence and debug with clarity once you have a complete mental model of Ember events!