【问题标题】:Multiple events firing on view render在视图渲染上触发多个事件
【发布时间】:2023-05-25 14:09:01
【问题描述】:

我正在使用 Backbone.js 构建一个应用程序,但是我遇到了一个我无法尽早解决的问题。

我现在有一个简单的列表/详细视图设置,但每次我渲染详细视图时,我的事件都会变得复杂。例如显示两个详细视图,单击一个链接将导致它被单击两次。

我的视图如下所示(用 CoffeeScript 编写):

#
# Project List View
#
class ProjectListView extends Backbone.View

  el: $("#projectList")

events : {
  "click #addProject" : "createNewProject"
}

initialize : ->
  @template = _.template(app.projectListView)
  _.bindAll(this, "render", "createNewProject")
  @render()

createNewProject : (e) ->
  e.preventDefault()
  e.stopPropagation()
  tempProject = Projects.create({
    title : 'Test Project'
    description : ''
    browserDefault : 12
    lineHeight : 21
  })

render : =>
  $(@el).html(@template())
  @delegateEvents()
  return @

显然,事件已经结束,我没有触发任何点击事件。我在这里错过了什么?

【问题讨论】:

    标签: backbone.js coffeescript


    【解决方案1】:

    您粘贴的代码似乎没有正确缩进。原来是这样的吗?

    您不需要_.bindAll 行。相反,只需使用 => 来定义您的方法(而不是 ->

    按照 Julien 的建议,我做了一些风格上的更改并去掉了额外的 @delegateEvents。看看这是否有效:

    class ProjectListView extends Backbone.View
    
      el: $("#projectList")
    
      events:
        "click #addProject" : "createNewProject"
    
      initialize: =>
        @template = _.template(app.projectListView)
        @render()
    
      createNewProject: (e) =>
        e.preventDefault()
        e.stopPropagation()
        tempProject = Projects.create
          title: 'Test Project'
          description: ''
          browserDefault: 12
          lineHeight: 21
    
      render: =>
        @el.html @template()
        @
    

    【讨论】:

    • 是的,这与一些代码整理相结合,它可以工作。这是因为我每次都在创建一个新视图,这不是我想做的。我不知道我可以删除 _bindAll 行,非常有趣,谢谢大家。当代码有点偏离时,代码正确缩进了格式。
    • 对于这段代码,你甚至不需要=>,因为主干将调用具有正确上下文的事件处理程序。
    • @rfunduk 是的。它更像是“为什么不呢?”功能。
    • @TrevorBurnham,好吧,因为使用 => 会导致生成更冗长的 javascript,并且在大多数情况下,您会无缘无故地受到性能影响:)
    • 以这个 sn-p 为例:coffeescript.org/…'
    【解决方案2】:

    这是我对您的代码的 cmets。 Backbone 将根据您的事件选项自动委托事件(使用 delegateEvents)。您不必在渲染函数中执行此操作(很可能是向您抛出双重事件的原因)。从渲染中删除 deleteEvents。

    另外,@el 已经被定义为一个 jQuery 对象,因此您不必在渲染中再次执行此操作。

    您会创建 2 个项目列表视图吗?如果是这样,ID 必须是唯一的......

    【讨论】: