× {{alert.msg}} Never ask again
Get notified about new tutorials RECEIVE NEW TUTORIALS

A better way to attach Event Listeners in Meteor

Dominik Ferber
Aug 24, 2015
<p>Usually Meteor developers use classes to attach event handlers to templates. <span style="color:rgb(95, 99, 102)">Abusing classes to attach event listeners is against</span><span style="color:rgb(95, 99, 102)"> the </span><a href="https://en.wikipedia.org/wiki/Separation_of_concerns">Separation of Concerns</a><span style="color:rgb(95, 99, 102)"> principle. </span>Even the <a href="https://www.meteor.com/tutorials/blaze/update-and-remove">official Meteor Tutorial</a> gets it "wrong" (it's not included to not confuse beginners). This quick tip shows an alternative way.</p> <p> </p> <h2 style="font-style:italic"><strong>Example of abusing classes</strong></h2> <pre><code class="language-html">&lt;template name="task"&gt; &lt;button class="delete"&gt;Remove&lt;/button&gt; &lt;/template&gt;</code></pre> <pre><code class="language-javascript">Template.task.events({ "click .delete": function () { // delete the task } });</code></pre> <p>In this example, the class <em>delete</em> is used to attach the event listener to the remove button. But this is not optimal, because classes are intended for styling, not for attaching events. Abusing classes to attach event listeners is against the <a href="https://en.wikipedia.org/wiki/Separation_of_concerns">Separation of Concerns</a> principle. When reading someone else's source code, how would you know whether an element's class is used for styling or to trigger events? Which classes are safe to delete and which are not? Abusing classes gets confusing really fast.</p> <p> </p> <h2 style="font-style:italic"><strong>A better way</strong></h2> <p>While developing one of my larger projects, I did something else and have kept it since. <strong>Use <em>data</em>-attributes to attach event listeners instead of classes.</strong></p> <pre><code class="language-html">&lt;template name="task"&gt; &lt;button class="delete" data-action="task/delete"&gt;Remove&lt;/button&gt; &lt;/template&gt;</code></pre> <pre><code class="language-javascript">Template.task.events({ "click [data-action='task/delete']": function () { // delete the task } });</code></pre> <p>As you can see, we are now using data-attributes to attach the event handler to the button. The square brackets are a CSS selector that selects elements based on their attributes. It is a little bit more to type, but so much more readable. And remember code is read more than it is written [1]. The designer can mess with the classes however he likes without being concerned about messing up your attached logic. I hope you adopt this tip and use it in your code base. I promise once you've started using it, you won't go back.</p> <p> </p> <p><em><strong>Update #1:</strong></em></p> <p>As some commenters have pointed out, it is possible to achieve the same separation of concerns by adding a prefix to all classes that will trigger actions, e.g. <em>"</em><em><strong>js-</strong>"</em>. You have to make sure nobody adds any styles to these classes, then they are an equal solution to achieve the same goal.</p> <p><em><strong>Update #2:</strong></em></p> <p>I have now switched to using classes with a <strong><em>js-</em></strong> prefix, as the official Meteor guide recommends this way in the section "<a href="http://guide.meteor.com/blaze.html#js-selectors-for-events">Use <em>js- </em>selectors for event maps</a>". I created a rule called <em><a href="https://github.com/dferber90/eslint-plugin-meteor/blob/master/docs/rules/prefix-eventmap-selectors.md">prefix-eventmap-selectors</a></em> in my <a href="https://github.com/dferber90/eslint-plugin-meteor">Meteor ESLint plugin</a> which can enforce event-map selectors use the <em>js-</em> prefix. The plugin also contains further modules ensuring you are following the Meteor guide and other best practices.</p> <p> </p> <p><em>I hope you enjoyed this quick tip and it helps you write cleaner code.<br> If you need help with your Meteor project, you can book me as your mentor.<br> Just send me a message with the button on the right.</em></p> <p><em>You can follow me on Twitter where I tweet about the bleeding edge of Web Development and Single Page Applications.<br> My Twitter handle is <a href="https://twitter.com/@dferber90">@dferber90</a>.</em></p> <p> </p> <p><span style="color:rgb(95, 99, 102)">[1]: </span><a href="http://%5B1%5D:%20http://blogs.msdn.com/b/oldnewthing/archive/2007/04/06/2036150.aspx"><span style="color:rgb(95, 99, 102)">http://blogs.msdn.com/b/oldnewthing/archive/2007/04/06/2036150.aspx</span></a></p>
comments powered by Disqus