Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone js re-rendering leaves the view eventless

Tags:

backbone.js

All,

I am buidling an app with Backbone JS and as per my methodology am firing a request to the server to update my local storage on each hashchange if the first model lookup is too old.

So what I am dealing with is this.

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

In the view I have bound a change event to the model pointing to render so that when that second request comes back the page just re-renders.

To you gents and ladies, I ask why does when the first page gets loaded all the events work (click and such) but if the view re-renders, they do not anymore?

Some code to help you out for the views, there is a nested view with a nested request:

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

... one more I swear ...

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

   initialize: ->
     this.render()

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

All of this has been generalized, but the concept is the same.

When that change event fires and everything gets refreshed and I click on a .inner, nothing happens.

Suggestions? I have tried to unbind and remove the views before the new render has taken place, also I have tried to delegateEvents on the end of all the render methods.

Thanks

--UPDATE--

The ItemView Template:

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

The showItem method in ItemView is just a simple redirect to the actual item:

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

I forgot to mention that ItemView's tagName is 'li' and ItemsView tagName is 'ul', so all this does is make a list on the page.

like image 690
cbarton.a Avatar asked Nov 13 '22 16:11

cbarton.a


1 Answers

Put this code in your render function:

this.delegateEvents();

Read the explanation here.

like image 98
spirit walker Avatar answered May 23 '23 02:05

spirit walker