backbone template nested in another template

10,418

Solution 1

The way I've dealt with this in the past is to define both views separately, and then when you render View1, create a new View2, render it, and insert it into View1. So:

window.View1 = Backbone.View.extend({
    render: function() {
        this.view2 = new View2();
        this.$('insert-view-here').append(this.view2.render().el);
    }
});

Solution 2

You should create subviews for this.

I like to privatize subviews in closure and return the public view.

var View = (function (BV) {
    var View, Subview;

    // Only this main view knows of this subview
    Subview = BV.extend({ 
        template: _.template( subtmpl ),

        render: function () {
            this.$el.html( this.template( this.model.toJSON() ) );
            return this;
        }   
    }); 

    View = BV.extend({
        template: _.template( tmpl ),

        render: function () {
            this.$el.html( this.template( this.model.toJSON() ) );

            var subview = new SubView({ model: this.model }); 

            // replace a div in your template meant for teh subview with the real subview
            this.$el.find( "#subview" ).replaceWith( subview.render().el );

            return this;
        }   
    }); 

    return View;

}(Backbone.View));

var view = new View({ model: user });
var subview = new Subview; // Reference Error

Solution 3

Another option that's useful when you need to include Template2 multiple times within Template1, say as <li> elements within a <ul>, is to pass a Template2 function into Template1. (From Rico Sta Cruz' Backbone Patterns.)

TasksList = Backbone.View.extend({
  // Template1, inlined in js.
  template: _.template([
    "<ul class='task_list'>",
      "<% items.each(function(item) { %>",
        "<%= itemTemplate(item) %>",
      "<% }); %>",
    "</ul>"
  ].join('')),

  // Template2, inlined in js.
  itemTemplate: _.template(
    "<li><%= name %></li>"
  ),

  render: function() {
    var html = this.template({
      items: tasks /* a collection */,
      itemTemplate: this.itemTemplate
    });

    $(this.el).append(html);
  }
});
Share:
10,418
mbr1022
Author by

mbr1022

Updated on July 27, 2022

Comments

  • mbr1022
    mbr1022 almost 2 years

    Is it possible to have a template nested inside a template and access via backbone view?

    For example I have View1 using Template1, and View2 using Template2. Template2 actually needs to be in a DIV inside of Template1. I put the DIV container for template2 inside template1 with the appropriate id, but it doesn't show when page is rendered. If I remove Template2 div container from inside Template1 and just put it in the page body it works fine.

    So just wondering if this is possible, or if I have to nest the views/models, etc. to make this work?

    The data in Template2 is not technically related to Template1 is just needs to display in a position on the page that's embedded in Template1.

  • Rob Fox
    Rob Fox over 10 years
    In this case how do you handle the change of the inner element? Do you always render from top down of can the inner element change itself somehow?
  • RTigger
    RTigger over 10 years
    Changes to the inner elements can be handled by the 2nd view, just as you would handle them in any other situation. If, for some reason, the parent view or model changes and requires the html to be re-rendered, the child views will be recreated within this render method.