全局引用b / t模板和视图

时间:2012-08-21 12:39:39

标签: javascript backbone.js coffeescript underscore.js marionette

当处理绑定到单个dom元素的特定事件时,我想要一种方法能够明确表明所讨论的元素有事件...而不用查看javascript(以及删除双引用)

例如,让我们来看看这个简单的模板:

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

我可以使用一个没有被任何模板解析器使用的符号(在我的例子中,我正在使用Play!,因此@已经出局),并让开发人员明白按钮绑定到一个事件(我实际上不确定这是否有效,但你得到了要点):

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

虽然使用~来表示绑定到事件的元素会起作用,但在应用程序中仍然引用了两次 - 一次在上面的模板中,一次在视图中:

class window.Page extends Backbone.Marionette.Layout

  template: '#template-page'

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

有更好的方法吗?事情出错很容易,并且在不了解后果的情况下意外地对html进行更改(特别是如果命名模式发展等)。我可以想到一种方法,但我遇到了一些麻烦。

或许,在视图中指定变量会很酷。

class window.Page extends Backbone.Marionette.Layout

  template: '#template-page'

  @doSomethingButton: 'button#do-something'

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

但我似乎无法将此信息提供给模板。我看到了类似的东西:How to pass additional variables in to underscores templates,但没有骰子。理想情况下,它看起来像这样:

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

然后我就拥有了我想要的知名度!以下是我一直在尝试的内容:http://jsfiddle.net/franklovecchio/FkNwG/248/

1 个答案:

答案 0 :(得分:0)

这(来自你的小提琴):

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

因各种原因无效:

  1. 插值在单引号字符串中不起作用。
  2. 您不能在对象键中使用任意表达式,因此切换到"click #{...}"将无济于事。
  3. 您尝试将button#do-something用作事件规范和id属性(id="<%= Page.doSomethingButton %>")并且没有任何意义。
  4. 您可以将doSomethingButton修复为id并在第一次创建实例时创建Page类的事件:

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

    演示:http://jsfiddle.net/ambiguous/Zzv34/

    这样可行,但我看不出它有多大帮助,你只是添加更多图层和令人困惑的东西。

    我不明白为什么你不使用数据属性:

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

    然后,如果有人在弄乱模板并看到date-is-bound="yes",他们就会知道其他东西关心该按钮的id,所以他们必须传播任何更改。

    您可以将一组明确的事件传递给delegateEvents,这样您就可以遍历模板的DOM并解释id属性来构建您的事件。您可以查找带有id前缀的do- s,然后将后缀映射到处理程序名称:

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

    但是现在你在两个地方都有方法名称,所以你仍然被困住了,但至少你会得到错误而不是沉默的混淆。