2011-10-03 21 views
5

Tutti,Backbone js ri-rappresentazione lascia l'eventless vista

sto buidling un app con Backbone JS e secondo la mia metodologia sto sparando un richiesta al server per aggiornare il mio storage locale su ogni hashchange se il primo modello la ricerca è troppo vecchia

Quindi quello che sto trattando è questo.

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

Nella vista ho legato un evento di modifica al modello che punta a rendere in modo che quando quella seconda richiesta torna alla pagina appena ri-rendering.

A voi signori e signore, chiedo perché quando viene caricata la prima pagina tutti gli eventi funzionano (clic e così via) ma se la vista viene nuovamente visualizzata, non lo fanno più?

codice per aiutare fuori per il punto di vista, c'è una vista nested con una richiesta nidificato:

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)) 
    @ 

... un altro giuro ...

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

    initialize: -> 
    this.render() 

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

Tutto questo è stato generalizzato, ma il concetto è lo stesso.

Quando l'evento di modifica si attiva e tutto viene aggiornato e faccio clic su un .inner, non succede nulla.

Suggerimenti? Ho provato a separare e rimuovere le viste prima che il nuovo rendering abbia avuto luogo, inoltre ho provato a delegareEvents alla fine di tutti i metodi di rendering.

Grazie

--UPDATE--

L'ItemView Template:

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

Il metodo showItem in ItemView è solo un semplice redirect alla voce reale:

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

Ho dimenticato di menzionare che ItemView's tagName è 'li' e ItemsView tagName è 'ul', quindi tutto ciò è fare una lista sulla pagina.

+2

come si presenta il modello per ItemView? inoltre, che aspetto ha il metodo 'showItem' di ItemView? –

+1

Puoi creare un jsFiddle? –

+0

Sto lavorando a un jsFiddle per adesso ma il post è stato aggiornato. –

risposta

0

Ok, ecco quello che ho fatto per risolvere questo fastidioso bug:

La Backbone.View viene fornito con il metodo unbind da Backbone.Events.

Quindi quello che faccio in sostanza è tenere traccia di ogni vista che creo e quando creo una vista diversa o rerenderò la vista di samve, non mi rilasso tutte le precedenti viste dal DOM.

Nel caso del mio esempio di cui sopra, qui è il codice che funziona per me:

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

inserire questo codice nella funzione di rendering:

this.delegateEvents(); 

Leggi la spiegazione here.

Problemi correlati