2013-01-02 39 views
4

如何手動使用預編譯的handlebars.js模板?手動使用預編譯的句柄模板

比方說,我們有

source = "<p>Hello, my name is {{name}}</p>" 
data = { name: "Joe" } 

目前,我有

template = Handlebars.compile(source) 
render: -> template(data) 

源是來自數據庫,並以削減編譯時間,我想用編譯步驟,用Handlebars.precompile(source)預編譯模板服務器端,然後使用類似的東西:

template = precompiled_template 
render: -> precompiled_template(data) 

precompiled_template是一個帶有函數定義的字符串,因此不起作用。

此外,我發現Hanlebars.compile(source)() == Handlebars.precompile(source),但瀏覽了句柄的源代碼後,它是編譯器和運行時,我仍然不知道如何實現這一點。

+0

有無你看看[handlebars_assets](https://github.com/leshill/handlebars_assets)是如何工作的?有可能有一堆Rails的噪音,但也許它會提供一些見解。 –

+0

感謝您的輸入;我檢查了它,但它提供了一個Sprockets引擎,它委託給其他東西,最後我也沒有跟蹤它。不過,我找到了答案,它使用eval,總體來說不是很漂亮,但至少它起作用,並且似乎提高了性能。 –

+0

有趣的是,在這裏,爲什麼這些答案都沒有被標記爲答案......丹尼爾似乎已經在他的答案中做了很多工作,並且很高興看到他爲之付出了回報。當另一個用戶(例如我自己)正在尋找答案時,它也使得它更容易實際上有一個被標記爲已接受的答案。 – Steve

回答

0

這個速度測試http://jsperf.com/handlebars-compile-vs-precompile/3給出了答案。

顯然,一個解決方案是eval()即生成的字符串,它將工作。

的代碼是

var data = { name: "Greg" }; 
var source = "<p>Howdy, {{ name }}</p>"; 

eval("var templateFunction = " + Handlebars.precompile(source)); 
var template = Handlebars.template(templateFunction); 

template(data); 
=> "<p>Howdy, Greg</p>" 

當然一個需要小心評估和可能是一個更好的解決方案存在。

+1

您也可以將字符串寫入包含大對象文字的JavaScript文件,該文字將模板名稱映射到它們的函數。然後將該JavaScript拖到客戶端。 –

+1

真的嗎?建議某人使用'eval()'真的不是一個好主意。 http://stackoverflow.com/questions/86513/why-is-using-the-javascript-eval-function-a-bad-idea – pseudosavant

+1

Pseudosavant,你想分享的任何替代品? –

4

如果你到現在還沒有找到正確的問題,答案很簡單。 Handlebars在命令行中附帶了一個C預編譯器,如果您可以訪問shell,那麼您可以簡單地編譯每個分隔的模板或將它們合併成一個文件。

您可以通過npm安裝Handlebars,或者在您的系統上構建它。 外殼上,你可以查看幫助文件

$>把手[ENTER]

你會看到一個幫助文件像> - ˚F - 輸出輸出文件等等等等。 - 米--min減小輸出

$>把手mysupertemplate.handlebars -f compiled.js -m( 「-m」 如果 你要來縮小js文件)

在瀏覽器中運行Handlebars.compile是一個巨大的性能損失,因此在將文件發送到瀏覽器之前,值得嘗試在服務器上進行預編譯。

要註冊的手把模板,在瀏覽器中,你必須加載它們像這樣:

var obj = {"foo":"bar"} 

var template = require("./mytemplate-file.js") // require.js example 
    template = template(Handlebars) // Pass Handlebars Only if the template goes mad asking for his Father 

var html = Handlebars.templates[template-name](obj) 

例如,如果你有更多然後在「模板文件」註冊一個模板,你將能夠後訪問在需要使用

var html = Handlebars.templates["templateName"]({"foo":"bar"}); 

你可以更進一步通過註冊文件中的所有知道助手和/或製作自傭工像這樣的諧音叫名字的所有模板..

*// This will be the helper in you app.js file* 

Handlebars.registerHelper("mypartials", function(partialName, data) { 
    var partial = Handlebars.registerPartial(partialName) || data.fn 
    Handlebars.partials[partialName] = partial 
}) 

而在你的模板文件,你可以把這個...

{{#mypartial "divPartial"}} 
    <div id="block"><h2>{{foo}}</h2><p>{{bar}}</p></div> 
{{/mypartial}} 

{{#mypartial "formPartial"}} 
    <form id="foo"><input type="text" value="{{foo}}" name="{{bar}}"></form> 
{{/mypartial}} 

現在,您可以通過調用

var html = Handlebars.partials["divPartial"]({"foo":"bar","bar":"foo"}) 
var formHtml = Handlebars.partials["formPartial"]({"bar":"bar","foo":"foo"}) 

希望這有助於有點訪問此文件..

+0

嘿丹尼爾,感謝您的回覆! 我同意,預編譯在基本情況下很簡單,但是我會在數據庫中有用戶上傳的模板。 我試圖使用服務器端JavaScript來預編譯服務器上的模板,然後將其存儲並在事後使用。 –

+0

我不知道你使用的是什麼樣的平臺,我的所有樣本都是基於節點的,並且爲了創建一個js文件(即使它是一個臨時文件),我寫了一個小的cli來執行argv參數,並基於該文件將編譯。 其實它並不重要,如果你使用php等,你可以使用節點寫入新的文件作爲js,json或其他。使用來自節點的REPL和FS模塊,應該可以完成您正在尋找的任務。 – Daniel