1
votes

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?

2
the reason "this.el" was undefined was because I missed "_.bindAll(this, render)". Just like the manual says about the context.ericbae

2 Answers

1
votes

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. :)

0
votes

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();