Is it possible to load handlebar template with script tag? Or define handlebar templates programmatically in Ember.js

ぐ巨炮叔叔 提交于 2019-12-02 17:12:54

Or define handlebar templates programatically in Ember.js

You can define templates programmatically by using Ember.Handlebars.compile, see http://jsfiddle.net/pangratz666/wxrxT/:

Ember.View.create({
    personName: 'Dr. Tobias Fünke',
    template: Ember.Handlebars.compile('Hello {{personName}}')
}).append();​

Or you add compiled templates to Ember.TEMPLATES array, see http://jsfiddle.net/pangratz666/58tFP/:

Ember.TEMPLATES['myFunkyTemplate'] = Ember.Handlebars.compile('Hello {{personName}}');

Ember.View.create({
    personName: 'Dr. Tobias Fünke',
    templateName: 'myFunkyTemplate'
}).append();​

I would recommend to use some tools like Richard Millan stated. Also take a look at interline/ember-skeleton which offers support for compilation of templates.

You can also patch Ember View to load templates on get

Em.View.reopen({
    templateForName: function(name, type) {
        if (!name) { return; }

        var templates = Em.get(this, 'templates'),
            template = Em.get(templates, name);

        if (!template) {
            $.ajax({
                url: 'templates/%@.hbs'.fmt(name),
                async: false
            }).success(function(data) {
                template = Ember.Handlebars.compile(data);
            });
        }

        if (!template) {
            throw new Em.Error('%@ - Unable to find %@ "%@".'.fmt(this, type, name));
        }

        return template;
    }
});

UPDATE: Since Ember 1.0.0-pre.3 this solution probabaly no more work (maybe can be migrated to recent Ember)

So since I still wanted separate files for my templates and I didn't want to define them in strings in the javascript I hacked this together last night

It is a synchronous lazy loader, it loads all the templates first, then ember and the rest of my code,

        //fake function so that every loads fine will get redefined in application.js
        function initializeApp(){}

        function loadTemplates(){
            var arg = arguments[0],
                next = Array.prototype.slice.call(arguments,1);
            if(typeof arg != 'string'){
                arg()
            }else{
                var scriptObj = document.createElement('script');
                scriptObj.type = 'text/x-handlebars';
                $(scriptObj).attr('data-template-name', arg.replace('.handlebars', '').substring(arg.lastIndexOf('/')+1))
                $.get(arg, function(data){
                    scriptObj.text = data;
                    document.head.appendChild(scriptObj);
                    if(next.length > 0) loadTemplates.apply(this, next);
                });
            }
        }

        function loadScripts() {
            var script = arguments[0],
                scriptObj = document.createElement('script'),
                next = Array.prototype.slice.call(arguments,1);
            scriptObj.type = 'text/javascript';
            scriptObj.src = script;
            scriptObj.onload = scriptObj.onreadystatechange = (next.length > 0) ? function(){loadScripts.apply(this, next)} : function(){$(document).ready(function() {initializeApp()})};
            document.head.appendChild(scriptObj);
        }

        function loadApp(obj){
            loadTemplates.apply(this, obj.templates.concat(function(){loadScripts.apply(this,obj.scripts)}))
        }

        window.onload = function(){
            loadApp({
                templates:
                    [
                        '/javascripts/views/templates/nav-bar.handlebars',
                    ],
                scripts:
                    [
                        'https://maps.googleapis.com/maps/api/js?sensor=false&callback=initializeGoogleMaps',
                        '/javascripts/lib/bootstrap.js', 
                        '/javascripts/lib/rails.js', 
                        '/javascripts/lib/ember.js',
                        '/javascripts/application.js',
                        '/javascripts/views/nav_bar.js',
                    ]
            })
        }

EDIT: I cleaned it up and made it work properly only testing in chrome though

It is possible, but you will need to precompile your templates first. This will also allow you to include all your templates within one file.

Later on, you will need to include the javascript file.

<script src="path/to/compiled/templates.js" type="text/javascript"></script>

If you load your templates into the DOM before loading Ember, then you don't need to compile or register your templates. Ember will come along after and do it for you.

Here is an article showing how:

http://weboriented.wordpress.com/2012/09/02/loading-handlebars-templates-in-ember-using-curl-js/

Here's another solution, inside your Ember view/component:

var viewClass = Ember.View.extend({ templateName: this.get('contentTemplate') });
var view = this.createChildView(viewClass);
var html = view.renderToBuffer().buffer;

This is an old question, so all the answers are a bit outdated. With Ember CLI templates are auto loaded by naming convention as require.js modules. It's a bit odd, since you write proposed ES6 import syntax and the build transpiles it into require.js syntax, but it works really well.

christian

It is possible, and yes, you can do it without usage of another another another tool, just using ember.js and nothing else. i did it like this:

1) html code. note that all handlebars files need to be loaded before using any of them. here, its just one file named handlebars.js

<body>
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
  <script>window.jQuery || document.write('<script src="js/libs/jquery-1.7.2.min.js"><\/script>')</script>
  <script src="js/libs/ember-0.9.8.1.min.js"></script>    
  <script src="js/handlebars.js"></script>
  <script src="js/app.js"></script>
</body>  

2) this file handlebars.js contains the following, using the compiler of ember

var src = "Hello, <b>{{name}}</b>";
Em.TEMPLATES["say-hello"] = Em.Handlebars.compile(src);

3) and then inside your app.js file, just use it as it were available (which it is):

var hu = Em.View.create({
    templateName: "say-hello",
    name: "Allô", 
    mouseDown: function() {  
    window.alert("hello world!");

  }
});

hu.appendTo("body");  
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!