Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ember.js with external handlebars template

So, I'm kind of new to Ember.js and it's been a couple of hours since I'm stuck with this. I'm playing with this bloggr client and what I want to accomplish is to load those handlebars templates from external files.

The "about" template should render when the user clicks the about page in the panel. Here's the code in short so you dont have to dig that much (I believe it'll be easy for experienced users)

Template inside .html as shown in the example

<script type="text/x-handlebars" id="about">
<div class='about'>
  <p>Some text to be shown when users click ABOUT.</p>
</div>

Now what I've done is to take that x-handlebar code away from the html page and placed it (without the <script type...>) and then put it in hbs/about.hbs

Now, inside the html page I've done something like this.

$.ajax({
    url: 'hbs/about.hbs',         
    async: false,
    success: function (resp) {
      App.About = Ember.View.extend({
        template: Ember.Handlebars.compile(resp),
      });
    }         
  });

The result of the ajax holds the content of the .hbs page, then I have to compile it so Ember can render it, right? Think that's what I did. But this is as far as I've come. Is what I've done right? What's the next move? I believe I have to append the content of the ajax call to the body or so.

Thanks in advance, after searching through SO I still wasn't able to make it run.

like image 909
Daniel Sh. Avatar asked Nov 09 '13 01:11

Daniel Sh.


1 Answers

You can attach a template to the object of available templates simply like so:

Ember.TEMPLATES.cow = Ember.Handlebars.compile("I'm a cow {{log this}}");

Or in your case maybe something like this:

var url = 'hbs/about.hbs',
    templateName = url.replace('.hbs', '');

Ember.$.ajax({
  url: url,         
  async: false,
  success: function (resp) {
    Em.TEMPLATES[templateName] = Ember.Handlebars.compile(resp);
  }         
});

Here's a lazy example of it being done in the application ready:

http://emberjs.jsbin.com/apIRef/1/edit

To be honest precompiling the templates beforehand (server side) is more performant for the end user.

Precompiling takes the raw handlebars and turns it into a plethora of javascript statements for use when building your views.

When the DOM is ready Ember scans the DOM for script elements of type "text/x-handlebars" and calls compile on their contents. It then adds the results to the Ember.TEMPLATES object with the name from the data-template-name attribute. This can add some completely unnecessary load time to the application.

For example when we sent in "I'm a cow {{log this}}" it was converted into the following javascript method

function anonymous(Handlebars,depth0,helpers,partials,data /**/) {
  this.compilerInfo = [4,'>= 1.0.0'];
  helpers = this.merge(helpers, Ember.Handlebars.helpers); data = data || {};
  var buffer = '', hashTypes, hashContexts, escapeExpression=this.escapeExpression;

  data.buffer.push("I'm a cow ");
  hashTypes = {};
  hashContexts = {};
  data.buffer.push(escapeExpression(helpers.log.call(depth0, "", {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
  return buffer;
}

minimized to something ugly like this:

function anonymous(e,t,n,r,i){this.compilerInfo=[4,">= 1.0.0"];n=this.merge(n,Ember.Handlebars.helpers);i=i||{};var s="",o,u,a=this.escapeExpression;i.buffer.push("I'm a cow ");o={};u={};i.buffer.push(a(n.log.call(t,"",{hash:{},contexts:[t],types:["ID"],hashContexts:u,hashTypes:o,data:i})));return s}

Depending on what your back-end is you can compile and bundle your templates before hand and send them down in the html so you can avoid spending time compiling the templates client side.

like image 147
Kingpin2k Avatar answered Oct 03 '22 05:10

Kingpin2k