Search code examples
javascripttemplatesbackbone.jsunderscore.js-templating

How to render model attributes in underscore template using a Backbone view


I have spent 2 days on the issue and can't seem to find the reason why the name value is not being passed to the underscore template.

I am fetching the User from a URL, which returns a value { "name": "UserName" } (and some more) which I can see in the console. Then I am fetching the model, and passing it to the View using the success callback. The template is rendered, though without the values.

In the view I can log the attributes, but they are not rendered in the underscore template.

Why is the name not being rendered in the template? There are no errors, and in the view I can log the attributes from the model.

I am using requirejs, backbone and underscore (and jekyll to create the html) and I have the following code:

Main

require([ 'app' ], function(App){
  App.initialize();
});

App

define(['jquery','underscore','backbone','users/model','users/view'
], function($, _, Backbone, User, ProfileLinkView){
  var initialize = function(){
        console.log("Working")
        user = new User();
        user.fetch({
            success : function(){
                console.log(user)
                var profileLink = new ProfileLinkView({ model : user });
                console.log("pL:", profileLink.el); 
            }
        });
    }
  return {
    initialize: initialize
  };
});

View

define(['backbone','users/model'], function( Backbone, User ) {

    var ProfileLinkView = Backbone.View.extend({
        el: '#profilelink',
        //template: _.template( "<a href='#'>Len</a>"),
        initialize : function(){
            this.render();

            this.listenTo(this.model, 'change', this.test);
        },
        test : function(){
            alert( "change" );
        },
        render: function() {
            console.log("v", this.model.attributes );
            data = this.model.attributes;
            this.template = _.template( "<a href='#'><%= name %></a>", this.model.toJSON() );
            this.$el.html( this.template( this.template() ) );
            return this;
        },
    })

    return ProfileLinkView
});

Model

define(['underscore','backbone',], function(_, Backbone, User){
    var User = Backbone.Model.extend({
        url: 'http://localhost:3000/users/0',
    })
    return User;
});

And the incorrect result

<li class="dropdown" id="profilelink"><a href="#"></a></li>

Which should be:

<li class="dropdown" id="profilelink"><a href="#">UserName</a></li>

Solution

  • I'm not sure about this part

    this.template = _.template( "<a href='#'><%= name %></a>", this.model.toJSON() );
    this.$el.html( this.template( this.template() ) );
    

    Can you try to change it to this?

    this.template = _.template( "<a href='#'><%= name %></a>");
    this.$el.html( this.template( this.model.toJSON() ) );
    

    Second parameter of underscore's template is template settings not the data. And you should pass the data into compiled template.