Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to render template other than application.hbs in EmberJS?

In EmberJS, the main template file is the application.hbs. Any template rendered from the routes goes the the {{outlet}} of this main template file.

Now, I have another main template file, say print.hbs wherein the template design is very different from the application.hbs. How do I do this?

In the router file, I have:

App.Router.map(function() {

    this.resource('print', function() {
        this.route('display1');
        this.route('display2');
    });

    this.route('dashboard', {path: '/'});
    this.route('anything');
});

The routes dashboard and anything uses the application.hbs. What should I do to use print.hbs on the print route? Please help.

like image 709
Melvin Avatar asked Jun 11 '14 09:06

Melvin


1 Answers

You can't easily change application template. Ember doesn't listen on templateName property changes and responds poorly when you try to re-render the template yourself.

A nice way to do this would be to use different partials within your application template, based on whether you are in the 'screen' or 'print' mode.

  <script type="text/x-handlebars">
    {{#if isPrint}}
      {{partial "application-print"}}
    {{else}}
      {{partial "application-normal"}}
    {{/if}}
  </script>

  <script type="text/x-handlebars" data-template-name="application-normal">
    <div id="app-normal">
      <h2>Normal template</h2>

      {{outlet}}
    </div>
  </script>

  <script type="text/x-handlebars" data-template-name="application-print">
    <div id="app-print">
      <h2>Print template</h2>

      {{outlet}}
    </div>
  </script>
App.ApplicationController = Ember.Controller.extend({
  isPrint: false,
  currentPathChange: function () {
    var currentPath = this.get("currentPath");
    var isPrint = currentPath ? currentPath.indexOf("print") === 0 : false;
    this.set("isPrint", isPrint);
  }.observes('currentPath').on("init")
});

This JSBin will demonstrate why this, unfortunately, doesn't work either. According to this bug report, Ember's handlebars gets confused when there are multiple outlet directives in the same page, even if they are in different #if scopes.

Until this gets fixed, I propose the following, slightly modified, solution.

Application template is empty. One template each for normal and print section.

  <script type="text/x-handlebars">
    {{outlet}}
  </script>

  <script type="text/x-handlebars" data-template-name="normal">
    <div id="app-normal">
      <h2>Normal template</h2>

      {{outlet}}
    </div>
  </script>

  <script type="text/x-handlebars" data-template-name="print">
    <div id="app-print">
      <h2>Print template</h2>

      {{outlet}}
    </div>
  </script>

In router, everything goes into normal and print resources. Normal resources are placed at /, so that all the links remain the same. No need for special coding in ApplicationController.

App.Router.map(function() {
  this.resource("print", function () {
    this.route("a");
    this.route("b");
  });

  this.resource("normal", {path: "/"}, function () {
    this.route("a");
    this.route("b");
  });
});

Working jsbin here.

like image 168
panta82 Avatar answered Sep 29 '22 12:09

panta82