David Jones
David Jones

Reputation: 10219

General structure of a Backbone application using Handlebars

Here's a basic outline of what's going on in my Backbone application:

  1. The router creates a new Profile view and passes in the username.
  2. When the new Profile is initialized, it creates a new User with the username that was passed in.
  3. The Profile then fetches details about this user.
  4. This is where I'm getting lost...

These are my questions:

  1. Am I using Backbone in the way that it was intended to be used, or should I re-think the structure?
  2. The Profile view has a render function which uses Handlebars. I need to be able to pass the user details to Handlebars in order to render the view. What's the best way to do this?
  3. Where should I actually call the render function?

Here's my code (note the commented questions):

Router

var Router = Backbone.Router.extend({
  routes: {
    ":username": "profile"
  },
  profile: function (username) {
    var profile = new Profile({username: username});
  }
});

Model

var User = Backbone.Model.extend({
  urlRoot: 'http://api.example.com/user'
});

View

var Profile = Backbone.View.extend({
  el: "#content section",
  initialize: function(username) {
    var user = new User({id: this.options.username});
    user.fetch({
      beforeSend: authenticate,
      success: function() {
        //*************************************************************
        // How do I make this result available to the render function?
        //*************************************************************
      },
    });
  },
  render: function() {
    alert(JSON.stringify(this.context));
    var source = $("#profile").html();
    var template = Handlebars.compile(source);
    //**********************************************************************
    // How do I set context equal to the result of the initialize function?
    //**********************************************************************
    var html = template(context);
    $("#content section").html(html);
  }
});

Upvotes: 0

Views: 145

Answers (2)

L. Sanna
L. Sanna

Reputation: 6552

  1. Am I using Backbone in the way that it was intended to be used, or should I re-think the structure?
  2. The Profile view has a render function which uses Handlebars. I need to be able to pass the user details to Handlebars in order to render the view. What's the best way to do this?
  3. Where should I actually call the render function?

Rayweb answered 2 already, so I'll answer 1 (and 3, but it's less important).

Question 1: yes you're doing it wrong. Why? You're creating the model inside the view, and you don't link the model to a view, which defeats the purpose of Backbone which is a MV* framework, not simply a OOP-facility. You should create the model then pass it as an argument to the view, that way you can share the info about one model in different views.

var model = new Model();
var view = new View({model:model});
var view2 = new View2({model:model});

That way you'll be able to update the model with this.model.fetch() and it will be accessible in every view as this.model with the updated data (as Rayweb showed in his code).

Concerning 3, call render anytime you want to refresh the view, no real rules about it.

Upvotes: 2

Rayweb_on
Rayweb_on

Reputation: 3727

Attach your user to the view, like this:

var Profile = Backbone.View.extend({
   el: "#content section",
   initialize: function(username) {
       self = this; 
       this.user = new User({id: this.options.username});
       this.user.fetch({
           beforeSend: authenticate,
           success: function() {
                self.render(); // as this.user is attached to the view, once its
                               // fetched it will be available to your render function
                               // just by using ..this.user.
           },
       });
  },
  render: function() {
     alert(JSON.stringify(this.user));
     var source = $("#profile").html();
     var template = Handlebars.compile(source);

     var html = template(this.user);
     $("#content section").html(html);
  }
 });

Upvotes: 1

Related Questions