2014-10-30 140 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