javascript - template - Eventos en vistas anidadas Backbone.js
backbonejs github (2)
Tengo una vista llamada DashboardView
que WidgetView
varias instancias de WidgetView
. Cada widget necesita tener sus propios enlaces de eventos. Por lo que puedo decir, estos enlaces se pierden cuando la vista se procesa y se agrega a la vista principal, es decir:
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)
Al hacerlo de esta manera, los eventos de clic en el elemento .config
del widget ahora se pierden. ¿Hay una mejor manera de mezclar las vistas anidadas en el elemento primario mientras se asegura que los controladores de eventos en la vista secundaria se canalicen correctamente?
Una solución que he visto para este problema viene en este artículo . Esto se ve bien, pero tengo curiosidad si hay una forma más elegante de resolver esto.
Su problema es que delegateEvents
espera un elemento único y no cambiante para su vista. Debido a que su función de render
crea un nuevo elemento cada vez, las vinculaciones creadas por delegateEvents
nunca se activan cuando hace clic en el elemento generado por el render
.
Afortunadamente, la versión actual de Backbone ofrece un método setElement
que reasignará su elemento con el argumento que usted proporcionó, y luego automáticamente llamará a delegateEvents
.
Prueba esto:
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
Entonces, la idea es esta:
(1) Dentro del método de render
WidgetView
, @el
(el elemento raíz de la vista) con los datos de su modelo a través de la plantilla. (Y observe cómo compilo la plantilla solo una vez ; no es necesario compilar la plantilla en cada operación de renderizado).
(2) Dentro de DashboardView
, @el
elemento raíz del widget - @el
- al DOM.
Lo que @el
es que los eventos de la vista delegan en su elemento raíz - @el
. Por lo tanto, desea trabajar con el elemento raíz explícitamente: dentro del render
, lo rellena y luego lo agrega al DOM.