2011-10-03 9 views
5

Todo,backbone.js re-representación deja la vista sin acontecimientos

estoy y búsqueda de una aplicación con backbone.js y como por mi metodología estoy disparando una petición al servidor para actualizar mi almacenamiento local en cada hashchange si el primer modelo la búsqueda es muy antigua.

Así que lo que estoy tratando es esto.

(hashchange) -> 
    fetch model -> 
    (if model expired [eg: grabbed from LS], fetch again in background) 
    render 

En la vista He atado un evento de cambio en el modelo de apuntado para rendir de manera que cuando esa segunda solicitud regresa la página vuelve a renderizar.

Para ustedes señoras y señores, me pregunto por qué cuando la primera página se carga todos los eventos funcionan (clic y tal) pero si la vista se renueva, ya no lo hacen?

algo de código para ayudarle por los puntos de vista, hay una vista anidada con una solicitud anidada:

class ShowView extends Backbone.View 
    template: +some template+ 
    initialize: -> 
    this.render() 
    @model.bind('change', this.render) 

    render: -> 
    $(@el).html(this.template(@model.toJSON()) 
    items = new ItemCollection 
    @model.set(items: items, {silent: true}) 
    @$items = new ItemsView(collection: items, el: @$('#posts')) 
    items.fetch() 
    +displayPage @el+ 
    @ 

class ItemsView extends Backbone.View 
    template: +some template+ 
    initialize: -> 
    @collection.bind('reset', this.render) 

    render: => 
    @collection.each((model) -> new ItemView(model: model)) 
    @ 

... una más Juro ...

class ItemView extends Backbone.View 
    template: +some template+ 
    events: 
    'click .inner': 'showItem' 

    initialize: -> 
    this.render() 

    render: -> 
    $(@el).html(this.template(@model.toJSON())) 
    @ 

Todos esto ha sido generalizado, pero el concepto es el mismo.

Cuando el evento de cambio se activa y todo se actualiza y hago clic en un .inner, no pasa nada.

Sugerencias? He tratado de desvincular y eliminar las vistas antes de que se haya realizado el nuevo render, también he intentado delegarEvents al final de todos los métodos de renderizado.

Gracias

--UPDATE--

La plantilla ItemView:

<a class="inner"> 
    <img src="item/image.gif" /> 
    <h3><%= title %></h3> 
    <p><%= description %></p> 
</a> 

El método showItem en ItemView es simplemente una redirección sencilla al artículo:

showItem: -> 
    window.location.hash = "#/posts/#{@model.id}/show" 

Olvidé mencionar que el TagName de ItemView es 'li' y ItemsView tagName es 'ul', entonces todo lo que hace es hacer una lista en la página.

+2

¿cómo se ve la plantilla de ItemView? Además, ¿a qué se parece el método 'showItem' de ItemView? –

+1

¿Puedes crear un jsFiddle? –

+0

Estoy trabajando en un jsFiddle en este momento, pero la publicación se ha actualizado. –

Respuesta

0

Ok, así que aquí es lo que hice para solucionar este molesto insecto:

El Backbone.View viene con el método de desvinculación de Backbone.Events.

Así que lo que hago en esencia es hacer un seguimiento de cada vista que creo y cuando creo una vista diferente o rerender la vista de samve, desvinculo todas las vistas anteriores del DOM.

En el caso del ejemplo anterior, aquí está el código que funciona para mí:

class ShowView extends Backbone.View 
    template: +some template+ 
    initialize: -> 
    this.render() 
    @model.bind('change', this.render) 

    render: -> 
    $(@el).html(this.template(@model.toJSON()) 
    items = new ItemCollection 
    @model.set(items: items, {silent: true}) 
    @$items.unbind() if @$items    # for the subview events 
    items.fetch() 
    @$items = new ItemsView(collection: items, el: @$('#posts')) 
    this.delegateEvents()     # For the current view events 
    +displayPage @el+ 
    @ 

    unbind: -> 
     super 
     @$items.unbind() if @$items 

class ItemsView extends Backbone.View 
    template: +some template+ 
    initialize: -> 
    @collection.bind('reset', this.render) 

    render: => 
    @collection.each((model) -> new ItemView(model: model)) 
    this.delegateEvents()     # For the current view events 
    @ 

Cheers, Cbarton

1

poner este código en su función de render:

this.delegateEvents(); 

Lee la explicación here.

Cuestiones relacionadas