Andrew
Andrew

Reputation: 238917

How to render a Backbone view inline?

I have a bit of legacy HTML that is returns a list of items via AJAX.

var xhr = $.get('/example');
xhr.done(function(data){
  $('#container').html(data);
});

I have refactored a piece of that HTML to use a Backbone View. I would like to render the view immediately, inline, without specifying a selector. Here is a simplified example of the HTML:

<ul>
  <li>
    Some stuff here
    <script>
      var view = new MyView();
      // render the view and put the html right here!
    </script>
  </li>
</ul>

I tried something like document.write(view.render().el) but that did not work correctly.

How can I render a Backbone View inline?

Update: The reason for this question is that there will be multiple list items and this view will be rendered multiple times. I didn't think it was necessary to create a unique ID for every list item just for the purpose of appending the Backbone view to each list item. I thought maybe there was an easy way to say "this parent" within a script tag. Maybe that is my real question...

Upvotes: 0

Views: 444

Answers (2)

cdanea
cdanea

Reputation: 468

Try something like this.

<ul>
  <li>
    Some stuff here
    <script id="use_an_id_for_safety">
      // I assume you instantiate correctly, but I explicitly use new here
      var view = new MyView({el: $(document.currentScript)});// or use the id
      view.render();
      // render the view and put the html right here!
    </script>
  </li>
</ul>

Here's the fiddle with the solution

Upvotes: 1

Thiago Negri
Thiago Negri

Reputation: 5351

The render function should render the view into its $el property.

After rendering, you may access the $el to get the rendered view. You can write it "inline" like this:

<ul>
  <li>
    Some stuff here
    <script>
      var view = MyView();
      view.render();
      document.write(view.$el.html());
    </script>
  </li>
</ul>

A complete example:

<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>

<script type="text/template" id="search_template">
  <label>Search</label>
  <input type="text" id="search_input" />
  <input type="button" id="search_button" value="Search" />
</script>

<script type="text/javascript">
    SearchView = Backbone.View.extend({
        render: function() {
            var template = _.template($("#search_template").html(), {});
            this.$el.html(template);
        }
    });

    var search_view = new SearchView();
    search_view.render();
    document.write(search_view.$el.html());
</script>

Note that this is not the way Backbone is meant to be used. This inlining won't work with events.

The correct way is to pass an appropriate element to the view's constructor. Or, you may append the element as a child of another to keep full functionality:

document.getElementById('foo').appendChild(myView.$el);

Upvotes: 2

Related Questions