События во вложенных представлениях Backbone.js - PullRequest
8 голосов
/ 04 марта 2012

У меня есть представление под названием DashboardView, которое создает несколько WidgetView s.Каждый виджет должен иметь свои собственные привязки событий.Насколько я могу судить, эти привязки теряются, когда представление визуализируется и добавляется в родительское представление, т.е.виджет теперь потерян.Есть ли лучший способ смешать вложенные представления в родительский, обеспечивая правильную передачу обработчиков событий в дочернем представлении?

Одно из решений этой проблемы, которое я видел, содержится в этой статье .Это выглядит правильно, но мне любопытно, есть ли более элегантный способ решения этой проблемы.

Ответы [ 2 ]

10 голосов
/ 04 марта 2012

Попробуйте это:

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

Итак, идея такова:

(1) Внутри метода WidgetView render вы заполняете @el (корневой элемент представления) данными своей модели через шаблон. (И обратите внимание, как я компилирую шаблон только один раз - нет необходимости компилировать шаблон при каждой операции рендеринга.)

(2) Внутри DashboardView вы добавляете корневой элемент виджета - @el - в DOM.

Дело в том, что события представления делегируются его корневому элементу - @el. Поэтому вы хотите явно работать с корневым элементом: внутри render вы заполняете его, а затем добавляете его в DOM.

1 голос
/ 04 марта 2012

Ваша проблема в том, что delegateEvents ожидает один неизменяемый элемент для вашего представления. Поскольку ваша функция render каждый раз создает новый элемент, привязки, сделанные с помощью delegateEvents, никогда не запускаются, когда вы нажимаете на элемент, сгенерированный с помощью render.

К счастью, текущая версия Backbone предлагает метод setElement , который переназначит ваш элемент с указанным вами аргументом, а затем автоматически вызовет delegateEvents.

...