Is it possible to load handlebar template with scr

2019-03-09 02:20发布

Simply enough I do not want to define all my handlebar templates in my html file

I tried this

<script type="text/x-handlebars" data-template-name="nav-bar" src="template.handlebar"></script>

But this did not work. Can I not define templates my template programmatically or even just load handlebar files so that I can reuse and also I feel it makes things a bit more maintainable.

I tried just loading them with ajax and appending them to the head, this works fine I can see it there but ember.js doesn't read it after ember has already been loaded and the templates are not defined.

8条回答
来,给爷笑一个
2楼-- · 2019-03-09 02:59

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.

查看更多
该账号已被封号
3楼-- · 2019-03-09 03:01

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)

查看更多
不美不萌又怎样
4楼-- · 2019-03-09 03:01

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");  
查看更多
淡お忘
5楼-- · 2019-03-09 03:06

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.

查看更多
爱情/是我丢掉的垃圾
6楼-- · 2019-03-09 03:10

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

查看更多
forever°为你锁心
7楼-- · 2019-03-09 03:10

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;
查看更多
登录 后发表回答