简体   繁体   English

Backbone.js嵌套视图中的事件

[英]Events in Backbone.js nested views

I have a view called DashboardView that instantiates multiple WidgetView s. 我有一个名为DashboardView的视图,它实例化了多个WidgetView Each widget needs to have its own event bindings. 每个小部件都需要有自己的事件绑定。 So far as I can tell, these bindings get lost when the view is rendered and added to the parent view, ie: 据我所知,当渲染视图并将其添加到父视图时,这些绑定会丢失,即:

class DashboardView extends Backbone.View
  constructor: -> 
    context = @
    _.each @collection, (w)->
      dv = new app.WidgetView(model: w)
      context.$el.append(dv.render()) 

class WidgetView extends Backbone.View
  events: 
     "click .config" : "config_widget"

  render: ->
      _.template($("#widget-template").html(), @model)

Doing it this way, the click events on the .config element of the widget are now lost. 这样做,窗口小部件的.config元素上的单击事件现在丢失了。 Is there a better way of mixing the nested views into the parent while ensuring that the event handlers on the child view are channelled correctly? 是否有更好的方法将嵌套视图混合到父级中,同时确保子视图上的事件处理程序正确引导?

One solution I have seen to this problem comes in this article . 我在这篇文章中看到了一个解决这个问题的方法。 This looks about right, but I'm curious if there is a more elegant way of solving this. 这看起来是正确的,但我很好奇是否有更优雅的方法来解决这个问题。

Try this: 尝试这个:

class DashboardView extends Backbone.View
  constructor: -> 
    @collection.each ( w ) =>
      dv = new app.WidgetView( model: w )
      @$el.append dv.render().el // Append widget's @el explicitly

class WidgetView extends Backbone.View
  tagName: 'div' // or whatever your view's root element is

  template: _.template $( "#widget-template" ).html() // pre-compile template

  events: 
    "click .config": "config_widget"

  render: ->
    @$el.html @template @model.toJSON() // append template to @el
    return this // return view

So, the idea is this: 所以,这个想法是这样的:

(1) Inside the WidgetView 's render method, you populate @el (the root element of the view) with its model's data via the template. (1)在WidgetViewrender方法中,通过模板填充@el (视图的根元素)及其模型的数据。 (And notice how I compile the template only once - there is no need to compile the template on each render operation.) (并注意我编译模板一次 - 不需要在每个渲染操作上编译模板。)

(2) Inside the DashboardView , you append the widget's root element - @el - to the DOM. (2)在DashboardView ,将小部件的根元素 - @el - 附加到DOM。

The thing is that the view's events delegate to its root element - @el . 问题是视图的事件委托给它的根元素 - @el Therefore, you want to work with the root element explicitly: inside render , you populate it, and then you append it to the DOM. 因此,您希望显式使用根元素:在render ,填充它,然后将其附加到DOM。

Your issue is that delegateEvents expects a single, non-changing element for your view. 您的问题是delegateEvents期望您的视图有一个不变的元素。 Because your render function creates a new element every time, the bindings made by delegateEvents are never fired when you click on the element generated by render . 因为您的render函数每次都会创建一个新元素,所以当您单击render生成的元素时, delegateEvents所做的绑定永远不会被触发。

Luckily the current version of Backbone offers a setElement method that will reassign your element with the argument you provide, and then it will automatically call delegateEvents . 幸运的是,当前版本的Backbone提供了一个setElement方法 ,该方法将使用您提供的参数重新分配元素,然后它将自动调用delegateEvents

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM