Templates 如何在外部文件中定义Handlebar.js模板

Templates 如何在外部文件中定义Handlebar.js模板,templates,handlebars.js,loading,external,Templates,Handlebars.js,Loading,External,我目前正在同一个HTML文件中定义我的把手模板,它们将在其中使用 是否可以将它们定义为外部模板,在加载页面时可以调用这些模板?您可以使用AJX加载它们 下面是一个示例函数,它接受指向把手模板的URL和回调函数。该函数加载模板,并使用已编译的Handlebar模板作为参数调用回调函数: function loadHandlebarsTemplate(url, callback) { var xhr = new XMLHttpRequest(); xhr.open('GET', ur

我目前正在同一个HTML文件中定义我的把手模板,它们将在其中使用


是否可以将它们定义为外部模板,在加载页面时可以调用这些模板?

您可以使用AJX加载它们

下面是一个示例函数,它接受指向把手模板的URL和回调函数。该函数加载模板,并使用已编译的Handlebar模板作为参数调用回调函数:

function loadHandlebarsTemplate(url, callback) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4 && xhr.status == 200) {
            var raw = xhr.responseText;
            var compiled = Handlebars.compile(raw);
            callback(compiled);
        }
    };
    xhr.send();     
}
例如,假设您在名为/templates/MyTemplate.html的文件中定义了一个把手模板,例如:

<p>The current date is {{date}}</p>

更好的解决方案是预编译模板,这样可以加快加载时间。可以找到更多关于预编译的信息。

对于那些像我一样通过谷歌搜索来到这里的人,我终于在这篇文章中找到了完美的答案,请查看:

基本上,您需要实现一个方法getTemplate:

Handlebars.getTemplate = function(name) {
    if (Handlebars.templates === undefined || Handlebars.templates[name] === undefined) {
        $.ajax({
            url : 'templatesfolder/' + name + '.handlebars',
            success : function(data) {
                if (Handlebars.templates === undefined) {
                    Handlebars.templates = {};
                }
                Handlebars.templates[name] = Handlebars.compile(data);
            },
            async : false
        });
    }
    return Handlebars.templates[name];
};
然后使用它调用您的模板:

var compiledTemplate = Handlebars.getTemplate('hello');
var html = compiledTemplate({ name : 'World' });
这样,如果您预编译了模板(非常适合生产使用),它将直接找到它,否则它将获取模板并在浏览器中编译(这就是您在开发中的工作方式)。

编辑解决方案以在目录中使用更多模板,如果我不希望所有模板都位于
templates
目录中

Handlebars.getTemplate = function(name, dir) {

    if (dir === undefined) //dir is optional
        dir = "";

    if (Handlebars.templates === undefined || Handlebars.templates[name] === undefined) {
        $.ajax({
            url : 'templates/' + dir+'/' + name,    //Path, dir is optional
            success : function(data) {

                if (Handlebars.templates === undefined) {
                    Handlebars.templates = {};
                }

                if (Handlebars.templates[dir] === undefined) {
                    Handlebars.templates[dir] = {};
                }

                if (dir === undefined)
                    Handlebars.templates[name] = Handlebars.compile(data);
                else
                    Handlebars.templates[dir][name] = Handlebars.compile(data);
            },
            async : false
        });
    }

    if (dir === undefined)
        return Handlebars.templates[name];
    else
        return Handlebars.templates[dir][name];
};

使用
async:false
远远不是完美的解决方案。使用工具箱中的jQuery,只需使用$.Deferred

我提出了这个解决方案:

;(function ($, Handlebars) {
    'use strict';

    var namespace   = window,
        pluginName  = 'TemplateEngine';

    var TemplateEngine = function TemplateEngine(options) {
        if(!(this instanceof TemplateEngine)) {
            return new TemplateEngine(options);
        }

        this.settings = $.extend({}, TemplateEngine.Defaults, options);
        this._storage = {};

        return this;
    };
    TemplateEngine.Defaults = {
        templateDir: './tpl/',
        templateExt: '.tpl'
    };

    TemplateEngine.prototype = {
        constructor: TemplateEngine,

        load: function(name, $deferred) {
            var self = this;
            $deferred = $deferred || $.Deferred();

            if(self.isCached(name)) {
                $deferred.resolve(self._storage[name]);
            } else {
                $.ajax(self.urlFor(name)).done(function(raw) {
                    self.store(name, raw);
                    self.load(name, $deferred);
                });
            }

            return $deferred.promise();
        },
        fetch: function(name) {
            var self = this;

            $.ajax(self.urlFor(name)).done(function(raw) {
                self.store(name, raw);
            });
        },
        isCached: function(name) {
            return !!this._storage[name];
        },
        store: function(name, raw) {
            this._storage[name] = Handlebars.compile(raw);
        },
        urlFor: function(name) {
            return (this.settings.templateDir + name + this.settings.templateExt);
        }
    };


    window[pluginName] = TemplateEngine;

})(jQuery, Handlebars);
;(function ($, Handlebars) {
    'use strict';

    var namespace   = window,
        pluginName  = 'TemplateEngine';

    var TemplateEngine = function TemplateEngine(options) {
        if(!(this instanceof TemplateEngine)) {
            return new TemplateEngine(options);
        }

        this.settings = $.extend({}, TemplateEngine.Defaults, options);
        this._storage = {};

        return this;
    };
    TemplateEngine.Defaults = {
        templateDir: './tpl/',
        templateExt: '.tpl'
    };

    TemplateEngine.prototype = {
        constructor: TemplateEngine,

        load: function(name, $deferred) {
            var self = this;
            $deferred = $deferred || $.Deferred();

            if(self.isCached(name)) {
                $deferred.resolve(self._storage[name]);
            } else {
                $.ajax(self.urlFor(name)).done(function(raw) {
                    self.store(name, raw);
                    self.load(name, $deferred);
                });
            }

            return $deferred.promise();
        },
        fetch: function(name) {
            var self = this;

            $.ajax(self.urlFor(name)).done(function(raw) {
                self.store(name, raw);
            });
        },
        isCached: function(name) {
            return !!this._storage[name];
        },
        store: function(name, raw) {
            this._storage[name] = Handlebars.compile(raw);
        },
        urlFor: function(name) {
            return (this.settings.templateDir + name + this.settings.templateExt);
        }
    };


    window[pluginName] = TemplateEngine;

})(jQuery, Handlebars);