在Handlebars.js中使用预编译的模板(jQuery Mobile环境)


67

我在预编译Handlebars中的模板方面有些挣扎。我的jQuery Mobile项目在模板方面越来越大,我希望预先编译所使用的模板。

但是我似乎找不到很好的解释(如循序渐进的教程)来说明如何使用把手。

我仍然使用script标签将所有模板内联。我已经使用NPM安装了车把。但是现在我有点迷失了如何进行。

我猜正在做类似的事情

handlebars -s event.handlebars > event.compiled

并以某种方式包括event.compiled内容?但是,怎么称呼它。

我这样称呼我的模板

var source = $('#tmpl_profile').html(),
template = Handlebars.compile(source),
context = user.profile()),
html    = template(context);

希望有人能为我阐明这一点。

Answers:


115

因此,经过反复尝试(这是学习它的最佳方法),这是对我有效的方法。

首先,外部化所有模板,假设您在脚本标签中有一个模板,例如

<script id="tmpl_ownevents" type="text/templates">
    {{#unless event}}
        <div class="notfoundevents"><p>No events for you</p></div>    
    {{/unless}}
</script>

创建一个名为events.tmpl的新文件,然后将模板复制/粘贴到该文件中。确保删除脚本元素本身,这有点困扰我。

像这样安装Handlebars命令行脚本

npm install -g handlebars

转到已将events.tmpl保存到的文件夹并运行

handlebars events.tmpl -f events.tmpl.js

包含Handlebars.js之后,将已编译的javascript包含到HTML中

<script src="events.tmpl.js"></script>

现在剩下的就是将普通模板代码更改为类似于以下内容的代码

var template = Handlebars.templates['events.tmpl'], // your template minus the .js
    context = events.all(), // your data
    html    = template(context);

超级快捷的预编译把手模板就在您的手中。


28
从语义上讲,我发现最好不要给模板文件加上“ js”扩展名,因为这些文件不是“纯” javascript文件。handlebars编译器会理解“ handlebars”扩展名,并将其从最终模板名称中删除,因此对于events.handlebars而不是Handlebars.templates ['events.tmpl']; 你会得到Handlebars.templates ['events']; 我觉得比较干净。
彼得·帕杰赫

7
对于那些使用RequireJS的用户,handlebars命令行实用程序中有一个选项(-a--amd),告诉它创建一个AMD样式函数,您可以稍后使用RequireJS加载该函数。
眼睛

@PeterPajchl您的回答有点混乱,从表面上看对我没有用,所以我想为他人澄清一下。是的,编译之前先命名模板文件“ name.handlebars” ,然后选择将其输出到“ name.js”(然后在html文件中引用),将得到Handlebars.templates ['name']。但是,这并不意味着您应该将文件输出到“ name.handlebars”并在html中进行引用。
rvr_jon

6
您必须为多个模板拥有多个文件吗?有人可以解释您如何外部化10多个模板吗?理想情况下,它们全部放在一个文件中,并且通过删除脚本标签,您已经删除了特定模板可能具有的唯一标识。
Rey

3
@ xckpd7您不需要外部化模板,请参见小提琴;因此,您可以编译任何数量的车把并将它们连接到单个文件中,编译时间名称将决定Handlebars.templates属性
ertrzyiks 2013年

15

另一个很好的选择是使用GruntJS。安装完成后:

npm安装grunt-contrib-handlebars --save-dev

然后在您的gruntfile.js中

grunt.initConfig({
    dirs: {
      handlebars: 'app/handlebars'
    },
    watch: {
      handlebars: {
        files: ['<%= handlebars.compile.src %>'],
        tasks: ['handlebars:compile']
      }
    },
    handlebars: {
      compile: {
        src: '<%= dirs.handlebars %>/*.handlebars',
        dest: '<%= dirs.handlebars %>/handlebars-templates.js'
      }
    }
});


grunt.loadNpmTasks('grunt-contrib-handlebars');

然后,您只需grunt watch在控制台中键入内容,grunt就会自动将所有* .handlebars文件编译到您的handlebars-templates.js文件中。

真正有效的使用把手的方式。


10

这是我的方法:

制备

我们只假设您所有的模板变量都在一个名为的变量中context

var context = {
    name: "Test Person",
    ...
};

放置模板的位置

创建一个包含所有模板的目录(我们将其templates/称为)filename.handlebars。在此处添加您的模板,称为。

您的目录结构:

.
└── templates
    ├── another_template.handlebars
    └── my_template.handelbars

编译模板

首先转到您的根目录,然后使用npm CLI程序编译模板:

handlebars templates/*.handlebars -f compiled.js

新目录结构:

.
├── compiled.js
└── templates
    ├── another_template.handlebars
    └── my_template.handlebars

用法

包含compiled.js运行时后,在HTML页面中包含:

<script src="handlebars.runtime.js"></script>
<script src="compiled.js"></script>

使用全局Handlebars对象渲染模板:

// If you used JavaScript object property conform file names
// Original filename: "my_template.handlebars"
Handlebars.templates.my_template(context)

// if you used special characters which are not allowed in JavaScript properties
// Original filename: "my-template.handlebars"
Handlebars.templates["my-template"](context)

备注

注意文件扩展名.handlebars。编译模板时会自动删除它。

另外:如果您将Jetbrains IDE之一与Handlebars / Mustache插件一起使用,您甚至可以获得很好的编辑器支持。


我正在考虑使用此方法来加载我的预编译模板,但我想在开始实现这一点之前先了解一件事。是否可以通过require.js加载handlebars.runtimecompiled.js?..
Wracker 2015年

我对requirejs并不了解,但是您应该将其定义handlebars.runtime为的依赖项compiled.js(而您的脚本也将其定义compiled.js为依赖项)。您可以手动执行此操作(通过将已编译的代码手动包装在定义中),也可以查找现有的库来为您执行此操作。
apfelbox 2015年

@apfelbox什么是npm CLI,以及如何将其添加到VS 2015?
托马斯

6

用Grunt预编译车把模板

假设您已经安装了Node.js。如果不这样做,那就去做。

1)设置节点依赖性:

在您的应用程序根目录中,添加一个名为的文件package.json。将以下内容粘贴到该文件中:

{
  "devDependencies": {
   "grunt-contrib-handlebars": "~0.6.0",
    "grunt-contrib-watch": "~0.5.3",
    "handlebars": "~1.3.0"
  },
}

此JSON文件告诉Node需要安装哪些软件包。如您将在下一步中看到的那样,这有助于使其他开发人员非常快速地启动和运行。

2)安装节点依赖项:

在终端/命令提示符/ powershell中,cd进入项目的根目录并运行以下命令:

npm install grunt -g
npm install grunt-cli -g

并安装package.json中列出的依赖项:

npm install

现在,您已经安装了所需的所有节点依赖项。在项目的根目录中,您会看到一个node_modules folder

3)配置Grunt:

在您的项目根目录中,创建一个名为的文件Gruntfile.js。将以下内容粘贴到该文件中:

module.exports = function(grunt) {

    var TEMPLATES_LOCATION        = "./src/templates/",       // don't forget the trailing /
        TEMPLATES_EXTENSION       = ".hbs",
        TEMPLATES_OUTPUT_LOCATION = TEMPLATES_LOCATION,       // don't forget the trailing /
        TEMPLATES_OUTPUT_FILENAME = "compiled_templates.js";  // don't forget the .js

    grunt.initConfig({
        watch: {
            handlebars: {
                files: [TEMPLATES_LOCATION + '**/*' + TEMPLATES_EXTENSION],
                tasks: ['handlebars:compile']
            }
        },
        handlebars: {
            compile: {
                src: TEMPLATES_LOCATION + '**/*' + TEMPLATES_EXTENSION,
                dest: TEMPLATES_OUTPUT_LOCATION + TEMPLATES_OUTPUT_FILENAME,
                options: {
                    amd: true,
                    namespace: "templates"
                }
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-handlebars');
    grunt.loadNpmTasks('grunt-contrib-watch');

}

4)根据自己的喜好进行配置:

如果您没有使用Require.js,则需要更改handlebars.compile.options.amdfalse。您可能还想namespace根据自己的喜好调整选项。如果您使用的是require / amd模块,则namespace属性并不重要(如果将其删除,则默认为“ JST”)。

因为所有项目的结构都有些不同,所以您只需要配置Gruntfile。修改常量TEMPLATES_LOCATIONTEMPLATES_EXTENSIONTEMPLATES_OUTPUT_LOCATIONTEMPLATES_OUTPUT_FILENAME以满足您的项目。

如果您的模板分散在整个应用程序中,则需要更改TEMPLATES_LOCATION为最低的目录。确保模板与node_modules,bower_components或任何其他第三方目录隔离,因为您不希望Grunt将第三方模板编译为应用程序编译的模板。如果包括所有的在自己的代码./src./js./app目录,你会好起来的。

5)用Grunt编译模板:

要在后台运行grunt,请打开终端并cd进入项目的根目录,然后运行命令:(grunt watch:handlebars同样grunt watch适用)。在后台运行grunt时,将自动编译对模板文件的所有更改,并handlebars.compile.dest根据需要重写指定的输出文件。输出将如下所示:

Running "watch" task
Waiting...

要单独运行编译任务,请打开终端并cd进入项目的根目录,然后运行命令:(grunt handlebars:compile同样grunt:handlebars适用)。输出将类似于:

Running "handlebars:compile" <handlebars> task
File "./src/templates/compiled_templates.js" created.

Done, without errors.

3

对于把手2.0.0 alpha更新:

@Macro已经非常清楚地解释了它如何与1个模板一起工作,请参见此答案以了解如何使handlebars.js工作

如果在使用预编译模板时看到“ TypeError:'undefined'不是一个函数”:

评估templateSpec.call(容器,Handlebars,上下文,options.helpers,options.partials,options.data)时,在“ handlebar.runtime.js”第436行发生此错误,

因为安装的编译器npm与浏览器使用的不匹配。下载的最新稳定版本是v1.3.0,如果您使用npm install handlebars,它将为您安装2.0.0-alpha4。

请使用检查

handlebars any_your_template_before_compile.handlebars | grep "compiler"

如果您确实安装了车把2.0.0-alpha4,它将为您提供:

this.compiler = [5, '>=2.0.0']

第一个数字代表您的车把编译器的版本。在浏览器控制台中输入以下代码,查看结果是否与版本匹配。

Handlebars.COMPILER_REVISION

如果您的编译器5的浏览器版本为4,那么您将遇到上述问题。

要修复它,请使用以下命令安装车把1.3.0

npm install handlebars@1.3.0 -g

然后尝试再次编译它,这一次您会看到,它为您提供了匹配的版本信息,并且您可以使用预编译的模板。

this.compilerInfo = [4, '>=1.0.0']


请解释一下您是否有大量的模板:

首先将每个支撑模板外部化:event.handlebars,item.handlebars等...您可以将它们全部放在一个文件夹中,说“ / templates”

编译所有文件,并使用以下命令将其串联为1个文件:

handlebars *.handlebars -f templates.js

并在您的HTML中包含handlebars.runtime,此文件

<script src="/lib/handlebars.runtime.js"></script>
<script src="templates.js"></script>

模板将按其名称注入到Handlebars.templates中。例如,可以通过Handlebars.tempaltes ['event']访问event.handlebars。


使用v2.0.0-alpha.4,我不得不调用Handlebars.template(Handlebars.templates.MYTEMPLATE)(CONTEXT)使用我的预编译模板。似乎没有那么优雅,所以我错过了一些东西,或者只是阿尔法。不管怎样,我很高兴找到了答案。
Raine Revere 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.