0

When dealing with specific events bound to a single dom element, I'd like a way to be able to make it apparent that the element in question has events...without looking at the javascript (along with removing double referencing).

For example, let's take this simple template:

<script type="text/template" id="template-page">
   <button id="do-something">click me</button>
</script>

I could use a symbol that was not being used by any of the template parsers in question (in my case, I'm using Play!, so @ is out), and make it apparent to a developer that the button is bound to an event (I'm actually not sure if this works, but you get the gist):

<script type="text/template" id="template-page">
   <button id="~do-something">click me</button>
</script>

While using the ~ to represent an element bound to an event would work, it is still referenced twice in the app - once in the template above, and once in the view:

class window.Page extends Backbone.Marionette.Layout

  template: '#template-page'

  events:
    'click button#~do-something': 'doSomething'

Is there a better way to do this? It's very easy for things to go wrong, and to accidentally make a change to the html without understanding the consequences (especially if naming patterns evolve, etc). I can think of one way, but am having a little bit of trouble.

It would be cool to specify a variable in the view, perhaps.

class window.Page extends Backbone.Marionette.Layout

  template: '#template-page'

  @doSomethingButton: 'button#do-something'

  events:
    'click #{doSomethingButton}: 'doSomething'

I can't seem to get this information to a template, though. I saw something like so: How to pass additional variables in to underscores templates, but no dice. Ideally, it would look like this:

<script type="text/template" id="template-page">
   <button id="<%= Page.doSomethingButton %>">click me</button>
</script>

And then I'd have the visibility I want! Here's what I've been trying: http://jsfiddle.net/franklovecchio/FkNwG/248/

Community
  • 1
  • 1
  • I don't really understand your needs but could be the [custom data attributes](http://html5doctor.com/html5-custom-data-attributes/) helpful for you?. You always can use [jquery attribute selectors](http://stackoverflow.com/questions/4146502/jquery-selectors-on-custom-data-attributes-on-html5). – fguillen Aug 21 '12 at 13:45
  • I don't want to duplicate the dom ID between javascript and html, I want to reference an underscore variable in the template declared inside the view. This would make it more transparent when viewing only the html as to which classes/ids were bound. What you mentioned doesn't seem pertinent :) –  Aug 21 '12 at 16:35

1 Answers1

0

This (from your fiddle):

@doSomethingButton: 'button#do-something'
events:
  'click #{@doSomethingButton}': 'doSomething'

doesn't work for various reasons:

  1. Interpolation doesn't work inside single quoted strings.
  2. You can't use arbitrary expressions in object keys so switching to "click #{...}" won't help.
  3. You're trying to use button#do-something as an event specification and as an id attribute (id="<%= Page.doSomethingButton %>") and that doesn't make any sense.

You could fix doSomethingButton to be just an id and create your Page class's events the first time an instance was created:

@doSomethingButton: 'do-something'
initialize: ->
   if(!@constructor::events)
     key = "click button##{Page.doSomethingButton}"
     @constructor::events = { }
     @constructor::events[key] = 'doSomething'

Demo: http://jsfiddle.net/ambiguous/Zzv34/

This works but I don't see how it is helpful, you're just adding more layers and confusing things.

I don't see why you don't use a data attribute:

<script type="text/template" id="template-page">
   <button id="do-something" data-is-bound="yes">click me</button>
</script>

then if anyone is messing around with the template and sees date-is-bound="yes", they'll know that something else cares about the id of that button so they'll have to propagate any changes.

You can pass an explicit set of events to delegateEvents so you could walk the DOM of your template and interpret the id attributes to build your events. You could look for ids with a do- prefix and then map the suffix to a handler name:

events = { }
@$('[id^=do-]').each (i, el) ->
  events["click ##{el.id}"] = el.id.match(/(?:do-)(.*)/)[1]
@delegateEvents(events)

But now you have the method name in two places so you're still stuck but at least you'll get an error rather than silent confusion.

mu is too short
  • 426,620
  • 70
  • 833
  • 800