Handlebars,加载外部模板文件

Handlebars, loading external template files

本文关键字:文件 外部 加载 Handlebars      更新时间:2023-09-26

我的目标是将所有Handlebars模板放在一个文件夹中,如下所示:

templates/products.hbs
templates/comments.hbs

我通过粗略的谷歌搜索在几个地方找到了这个片段,它显然会在外部文件中加载Handlebar模板,这比在一个索引文件中放置一堆模板更有意义。

(function getTemplateAjax(path) {
    var source;
    var template;
    $.ajax({
        url: path, //ex. js/templates/mytemplate.handlebars
        cache: true,
        success: function(data) {
            source    = data;
            template  = Handlebars.compile(source);
            $('#target').html(template);
        }               
    });         
})()

问题是,我不理解这个函数,也不知道如何使用它。为什么整个函数都用括号括起来,然后进行函数调用?例如(function x() { ... })()我不知道这是在做什么。

如果我没有错的话,看起来$('#target')是硬编码的,而它不应该是。此外,这不是应该在某个地方设置一个data变量,这样模板中引用的变量就可以工作吗??似乎正确的功能应该是:

function getTemplateAjax(path, target, jsonData) {
  var source;
  var template;
  $.ajax({
    url: path, //ex. js/templates/mytemplate.handlebars
    cache: true,
    success: function(data) {
      source    = data;
      template  = Handlebars.compile(source);
      $(target).html(template(jsonData));
    }               
  });         
}

附带说明:如果有人能给我推荐一个更好的模板引擎,一个真正支持外部模板文件的引擎,并且比Handlebars组织得更好,我将永远感激。

另一个问题是:我实际上无法将我的文件命名为mytemplate.hbs,因为当Ajax调用发生时,它会将其视为二进制文件,并以二进制文件的形式出现。我想这是一个将.hbs的服务器mime类型设置为text/html或text/plain的问题,但问题是这是一台Grunt服务器,我不知道如何更改其mime类型。

代码封装在IIFE(立即调用函数表达式)中,这意味着函数将立即执行。这就是以下含义:

(function x() {
  console.log('hello');
})();

你也可以做:

(function() {
  console.log('hello');
}());

IIFE通常用于创建";私人的";一段代码的作用域,使其与其他任何内容都很好(不冲突)。


您提供的第二个函数更有意义,也许第一个函数只是一个例子。
Handlebars允许您**预编译**模板,这样您就不必在运行时编译它们。同样,通过这种方式,您不必为了加载模板而发出额外的HTTP请求。

例如,如果我有以下项目结构-(请注意,我的模型、集合和视图都在main.js中,仅此示例,并且我的所有.js文件都在我的根目录中):

├── Gruntfile.js
├── handlebars-v2.0.0.js
├── index.html
├── main.js
├── package.json
└── templates
    └── todo.handlebars

我的"todo.hubbars"看起来像是带有handlebars语法的html:
<h3>{{title}}</h3>
<p>Created by: {{author}}</p>

要预编译我的模板,我会在命令行中执行以下操作(*您必须首先安装带有:`npm install-g handlebas`*的handlebas预编译脚本):
> handlebars templates/todo.handlebars -f todo.tpl.js

现在我的项目结构看起来是这样的:

├── Gruntfile.js
├── handlebars-v2.0.0.js
├── index.html
├── main.js
├── package.json
├── templates
│   └── todo.handlebars
└── todo.tpl.js

您将看到一个todo.tpl.js文件已添加到我的根目录中。如果我愿意的话,我可以给它命名一些不同的名称,只要扩展名是.js,因为该文件包含有效的JavaScript代码。此外,我还可以指定一个不同的目录来输出它。请记住,todo.tpl.js文件是Backbone View将使用的实际模板。您用todo.handlebars编写HTML,并将其编译为todo.tpl.js


现在我有了"todo.tpl.js"文件,我可以使用Grunt将我所有的js模板文件连接到"all_templates.js"文件中,或者我可以直接在HTML中引用每个文件,如下所示:
  <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
  <script src="http://documentcloud.github.io/underscore/underscore-min.js"></script>
  <script src="http://documentcloud.github.io/backbone/backbone-min.js"></script>
  <script src="handlebars-v2.0.0.js"></script>
  <script src="todo.tpl.js"></script> <!-- My Template for a Todo item -->
  <script src="main.js"></script>

在我的Backbone View中,在我的*main.js*文件中,我会得到这样的模板:
var TodoView = Backbone.View.extend({
  tagName: 'li',  
  className: 'todo-item',
  events: {
  },
  // You can grab your template function with the name you chose when
  // you precompiled it from: `Handlebars.templates`
  template: Handlebars.templates.todo,
  initialize: function(options) {
    this.listenTo(this.model, 'change', this.render);
  },
  render: function() {
    this.$el.html(this.template( this.model.toJSON() ));
    return this;
  }
});

你完了!更多信息请点击此处:
  • http://handlebarsjs.com/precompilation.html(断开;请参阅下一个链接)
  • https://handlebarsjs.com/api-reference/compilation.html#pre-汇编
  • https://www.npmjs.org/package/handlebars
  • http://code.tutsplus.com/tutorials/introduction-to-handlebars--net-27761(阅读其中有关预编译的内容

您可以从外部文件中读取模板,无需放置带有脚本标记的html

$.get('templates/products.hbs', function (data) {
    var template=Handlebars.compile(data);
    $(target).html(template(jsonData));
}, 'html')

我创建了一个简单的插件来实现这一点。有关此的详细信息:https://github.com/miketimmerman/load-template