1

This is my view for Backbone

var RepoListView = Backbone.View.extend({
  el: $('#wrapper'),

  events: {
    "click #more_repos" : "get_more_repos"
  },

  get_more_repos: function() {
    ajax(get_repo_url, {offset:2}, this.render);
  },

  render: function(result) {
    var template = Handlebars.compile($("#repos_hb").html());
    $(this.el).find('#main_content').append(template({repos: result}));
    return this;  
  }
});

And this is my ajax function that gets called from "get_more_repos" function

function ajax(url, data, post_ajax_function) {
  $.ajax({
    url: url, 
    data: data,
    dataType: 'json',
    success: function(result){
      post_ajax_function(result);
    }
  });    
}

However, it is not rendering, because "this.el" is undefined. Now after playing with it for awhile, it looks like the callback in "ajax(..)" function doesn't have access to "this.el". Any ideas how I can resolve this?

1
  • the reason "this.el" was undefined was because I missed "_.bindAll(this, render)". Just like the manual says about the context. Commented Sep 19, 2011 at 12:59

2 Answers 2

1

the problem is that the callback method is executed in the context of the ajax call, not in the context of your view. you need to use the _.bindAll method to correct this, in your view's initializer:

var RepoListView = Backbone.View.extend({
  el: $('#wrapper'),

  events: {
    "click #more_repos" : "get_more_repos"
  },

  initialize: function(){
    _.bindAll(this, "render");
  },

  get_more_repos: function() {
    ajax(get_repo_url, {offset:2}, this.render);
  },

  render: function(result) {
    var template = Handlebars.compile($("#repos_hb").html());
    $(this.el).find('#main_content').append(template({repos: result}));
    return this;  
  }
});

this will set up the render method to always execute in the context of the view, which will give you access to this.el even when used as a callback.

FYI - you may run into another issue related to el. if your view is defined before the DOM has finished loading, the jQuery call to $("#wrapper") will fail to find anything. to fix this, i typically put the jquery call in the view initializer, too.

initialize: function(){
  this.el = $("#wrapper");
  // ... other stuff here
}

there are other ways around this... but i wanted to include this note, just in case. :)

Sign up to request clarification or add additional context in comments.

3 Comments

I ran into the same problem noted in your FYI and ended up using the same solution...Is there any chance the DOM won't be ready on initialize?
if you initialize the view before the DOM is ready, then yes :) see this blog post: lostechies.com/derickbailey/2011/11/09/… it should fill you in on more info related to this.
Fantastic...not the first of your articles I've read...thanks for blogging!
0

At some point you have to call the render method. You'll need some code like the following:

var view = new RepoListView();
view.render();

In fact I would modify it slightly to look like this, removing the el definition from your view:

var view = new RepoListView({
    el: $('#wrapper')
});
view.render();

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.