2014-10-30 159 views
21

我的目标是把我所有的把手模板在一个文件夹中,像这样:车把,加载外部模板文件

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)); 
    }    
    });   
} 

附注:如果有人可以点我到一个更好的模板引擎,一个真正原生支持外模板文件,比车把组织得更好,我会感激不尽。

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

+1

我使用'text'插件for require.js为handlebars动态加载模板文件取得了很大的成功:https://github.com/requirejs/text – 2014-10-30 02:10:14

回答

44

该代码被包装在一个IIFE立即调用函数表达式),这意味着函数立即执行。这就是下面的方法:

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

你也可以这样做:

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

IIFEs常用使其起到很好的创造一段代码“私人”范围(不冲突)与其他任何事情。


您提供的第二个功能更有意义,也许第一个功能只是一个例子。


把手让您预编译你的模板,这样你就不必在运行时对它们进行编译。也是这样,您不必为加载模板而发出额外的HTTP请求。

例如,如果我有以下项目结构 - (请注意,我的模型,集合和视图都在之内。JS只是在这个例子中,我所有的.js文件都在我的根目录):

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


todo.handlebars看起来如此 - 只是把手语法HTML:

<h3>{{title}}</h3> 
<p>Created by: {{author}}</p> 


要预编译我的模板我会在命令行中执行以下操作(,您必须首先安装句柄预编译脚本:npm install -g handlebars):

> 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文件,我可以使用咕噜声来,也许CONCAT我所有的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> 


在我的骨干视图,这在我的情况下,住在我的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; 
    } 
}); 


你完成了!这里更多的信息:

+1

嘿顺便说一句,怎么会你建议我在开发过程中使用hbs?很明显,我不想在每次更改后重新编译模板。 (PS:我没有使用Backbone) – CaptSaltyJack 2015-02-11 15:49:07

+0

我个人使用GruntJS任务:https://github.com/gruntjs/grunt-contrib-handlebars - Gulp是另一种选择:https://www.npmjs.com/package/gulp-handlebars – istos 2015-02-11 19:55:41

+5

@istos哇!这真是一个非常好的答案..你很好地解释了每一点。 +1 – sachinjain024 2015-05-15 03:51:44

21

您可以从外部文件中读出的模板没有必要把HTML与脚本标记

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

可以使用任何其他扩展名,而不仅仅是* .hbs – 2015-03-30 11:54:53

+0

谢谢多诺万 - 这正是我一直在寻找的。 – 2017-01-20 16:09:09

+1

坚持* .hbs,这被WebStorm等人所认可。 – Molibar 2017-03-29 12:07:47

1

我已经创建了一个简单的插件来实现这一点。关于这个的更多信息:https://github.com/miketimmerman/load-template

+2

您可否将相关信息添加到答案本身这样它会完整并保留链接提供更多信息? – 2016-03-24 19:42:13