2012-03-24 77 views
19

我正在嘗試爲客戶端HTML/JS模板系統編寫適配器,以便在引擎蓋下使用dust.js。不幸的是,API期望渲染操作同步發生:渲染的輸出應該從render()調用返回。 Dust.js是異步的,並將渲染輸出傳遞給回調函數。有沒有什麼辦法可以解決這個問題,無論是在Dust API中,還是通過一些瘋狂的Javascript hack?是否有可能同步呈現dust.js模板?

+1

問得好!我想知道同樣的事情,因爲我想在CouchDB「show」函數(服務器端)中使用dust.js。 – 2012-03-27 17:33:51

+0

consolidationate.js有幫助嗎? – sntran 2012-04-02 17:28:19

+0

不幸的是,它看起來像鞏固.js提供的API使用一個回調函數,就像dust.js一樣,所以我認爲它不會對此有所幫助:/ – 2012-04-02 21:56:33

回答

16

DustJS只在需要渲染的資源(模板,部分)尚未全部加載時纔會異步執行。

如果在執行該模板之前加載模板的所有依賴關係,那麼它將同步執行(無論如何我都可以)。所以,你可以這樣做:

var result; 
dust.render("tpl", data, function(err, res) { 
    result = res; 
}); 
console.log(result); // result will actually already be filled out if dustjs didn't 
// have to go look for resources somewhere. 

這裏是下面一個更全面例如: (這裏是一個的jsfiddle鏈接,這樣你就可以運行它:http://jsfiddle.net/uzTrv/1/

<script type="text/javascript" src="dust.js"></script> 
<script> 
    var tpl = dust.compile("Omg {#people} {.} {/people} are here! {>partial/}", "tpl"); 
    var partial = dust.compile("I'm a partial but I've already been included so things still run {how}", "partial"); 
    dust.loadSource(tpl); 
    dust.loadSource(partial); 

    var data = { 
     people: ["jim", "jane", "jack", "julie"], 
     how: "synchronously!" 
    }; 

    var result; 
    dust.render("tpl", data, function(err, res) { 
     result = res; 
    }); 
    console.log(result); 
</script> 

有可能是案件(除我提到的那個)我錯在哪裏......我不知道關於dustjs的一切。

+0

已驗證。這是有效的,儘管你必須非常小心,不要做任何會使模板決定去異步的事情。 – heneryville 2012-06-05 22:01:09

+4

一個警告:dust.onload(可用於延遲加載模板/ partials)不是唯一可以異步的東西。您的JSON數據中的任何自定義助手或函數也可以通過調用chunk.map,然後進行ajax調用,setTimeout等來實現異步。因此,這絕對不是一個完整的證明解決方案。 – 2013-01-31 18:47:36

2

我也想要一個接受上下文並返回呈現灰塵文本的函數。這裏是我想出了一個解決方案:

// This function sets up dust template, and returns a new function "dusterFn()" 
// dusterFn() can be passed a Context, and will return the rendered text. 
// @param {String} text: The template text. 
// @param {String} [name]: The name of the template to register with dust. If none is provided, a random number is used. 
// @param {Function} [onError]: A function that is called if an error occurs during rendering. 
function getDusterFn(text, name, onError) { 

    var dusterFn = null; 
    name = name || Math.floor(Math.random() * 99999).toString(); 
    onError = onError || function (error) { }; 

    try { 

     var compiled = dust.compile(text, name) 
     dust.loadSource(compiled); 

     dusterFn = function (context) { 
      var dustOutput = ''; 
      dust.render(name, context, function (error, out) { 
       if (error) onError(error); 
       dustOutput = out; 
      }); 
      return dustOutput; 
     }; 

    } catch (e) { 
     // invalid template syntax 
     e += "\n\nPlease check your template syntax."; 
     throw (e); 
    } 

    return dusterFn; 

} 

使用

var greetingTemplate = getDusterFn('Hello {name}, You are {age} years old!'); 
greetingTemplate({name: 'Jane', age: 24}); 
0

馬特的解決方案給了我如何寫一個小包裝,隱藏了他的解決方案的「醜」一些指針(由「醜」我的意思是在回調之外聲明變量,在回調中分配值並返回外部回調)。

它不僅將黑客包裝成一個小函數,還綁定了模板的名稱。我發現這個令人難以置信的有用的,因爲我發現自己一遍又一遍地使用相同的渲染功能,但我不想每次都指定模板的名稱。

function templates(template) { 
    return function templatesWrapper(data) { 
    var result; 
    dust.render(template, data, function onRender(err, data) { 
     if (err) { 
     throw err; 
     } 
     result = data; 
    }); 
    return result; 
    } 
} 

這是如何使用它:

var renderHello = templates('hello.html'); 
renderHello({ username: 'Stackoverflow' }); 
// => <h1>Hello, Stackoverflow</h1>