Zev Isert
Zev Isert

Reputation: 1019

HTML DOM Templating: data-* versus closures for binding data

I came across two methods of handling events when templating HTML, and I don't have any intuition to go on for determining which is better.

Background

I am using lit-html, but the same problem applies to other methods of templating DOM in JS - think vue, angular, react.

Lit-html uses tagged template literal strings, allowing for this syntax

const inner = html`<span style="color: red">some text</span>`;
const example = html`
  <div>
    <p>${inner}</p>
  </div>
`;

to create this DOM

<div>
  <p>
    <span style="color: red">some text</span>
  </p>
</div>

With lit-html I can bind event handlers right in the markup using

<element on-click="${e => console.log(e)}" />

I can also loop over iterables to build up a bunch of DOM:

const items = [1, 2, 3, 4, 5];
const template = html`
 <div>
   ${items.map(item => html`<div>${item}</div>`)}
 </div>
`;

// Result
/* <div>
     <div>1</div>
     <div>2</div>
     <div>3</div>
     <div>4</div>
     <div>5</div>
   </div> */

Preface

Now say I want to bind event handlers to the elements that are made in map "loop".

I can see two ways to do so.

const items = [1, 2, 3, 4, 5];
const template = html`
 <div>
   ${items.map(item => html`
     <div on-click="${() => console.log(item)}">
       ${item}
     </div>
   `)}
 </div>
`;

or similarly...

const clickHandler = (e) => console.log(e.toElement.dataset['item']);

const items = [1, 2, 3, 4, 5];
const template = html`
 <div>
   ${items.map(item => html`
     <div
       data-item="${item}"
       on-click="${clickHandler}"
     >
       ${item}
     </div>
   `)}
 </div>
`;

Question

Which of the two methods above is a better choice? Answer for any reason - eg. Associated risks in security/data-loss, or differing performance, etc.

I have a tendency to do the first style. I call that closure binding, since I'm making new anonymous functions for each element.

Upvotes: 1

Views: 62

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074535

Which of the two methods above is a better choice?

It's entirely up to you and your use-case. A couple of things to feed into your decision process, though:

  • The closure approach creates a new function for each item every time you create a list of items; the attribute approach lets you reuse the same function (across items and across lists).
  • The closure approach allows for items that are not strings; the attribute approach works only for strings.
  • The closure approach keeps the data for the item out of the DOM; the attribute approach puts the data for the item in the DOM, as an attribute value, where it can be viewed (via Inspect Element) or even manipulated.

Upvotes: 2

Related Questions