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

后端 未结 8 493
臣服心动
臣服心动 2021-01-31 10:38

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

I tried this



        
相关标签:
8条回答
  • 2021-01-31 10:43

    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

    0 讨论(0)
  • 2021-01-31 10:45

    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;
    
    0 讨论(0)
  • 2021-01-31 10:45

    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.

    0 讨论(0)
  • 2021-01-31 10:47

    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)

    0 讨论(0)
  • 2021-01-31 10:58

    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.

    • If you are using Rails, you can use the ember-rails gem to do it for you.
    • Otherwise you can follow these instructions on how to precompile handlebars

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

    <script src="path/to/compiled/templates.js" type="text/javascript"></script>
    
    0 讨论(0)
  • 2021-01-31 10:58

    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/

    0 讨论(0)
提交回复
热议问题