2013-04-09 73 views
2

我試圖爲即將推出的項目選擇一個JS模板引擎,並且我的最愛之一似乎是dust.js在同步回調中​​使用dust.js(異步)

我喜歡它是異步的想法,即我只爲某個模板渲染渲染,當它準備好時,回調會將渲染的HTML插入到DOM中。

但我不確定如何解決同步回調中​​的異步渲染問題。例如 - 我經常使用DataTables插件,它提供了一些回調,允許我在實際插入之前修改DOM節點。

爲了說明問題 - 讓我們假設我有下面的代碼片段(從DataTables website採取和修改):

$(document).ready(function() { 
    $('#example').dataTable({ 
    "fnRowCallback": function(nRow, aData, iDisplayIndex, iDisplayIndexFull) { 
     // modify the node before it's actually inserted into the document 
     $('td:eq(4)', nRow).html('<b>' + aData[4] + '</b>'); 
    } 
    }); 
}); 

現在 - 我想擺脫'<b>' + aData[4] + '</b>',並使用一些方面,而不是渲染模板(這是一個微不足道的例子,但顯示了這個問題)。

如果我理解正確的話,我不能強迫dust.js同步呈現模板,因此它可能會發生未處理的節點將被插入到文檔(用戶將看到未加工的),後來當dust.js實際呈現該節點將被修改的模板。

從用戶的角度來看,這顯然不太好。

所以這是真的(dust.js不能被迫同步),如果是的話 - 如何應對呢?我是否應該使用同步引擎,如handlebarsmustache或者我在這裏看不到明顯的東西?

任何幫助或見解或建議將非常受歡迎。 謝謝! :)

編輯:

這個問題不是關於如何使一個模板,但如何確保它的fnRowCallback完成之前呈現。感謝@robertklep指出你的(刪除)答案。

+0

刪除,因爲我意識到這不是一個回答您的問題:)無論如何,你不能強迫一個異步函數要準備好fnRowCallback'完成之前',所以如果這是一個真正的問題我不知道認爲Dust.js是可用的。 – robertklep 2013-04-09 18:40:43

+0

是的,我注意到 - 謝謝你試圖幫助,但! :)是的 - 這就是我所擔心的 - 有些圖書館希望你從同步回調中​​返回(或者做某件事),而dust.js可能不會和他們一起玩:( – kgr 2013-04-09 19:11:22

回答

-2

編輯:爲了說清楚,我認爲這是一個不好的做法,你通常不應該這樣做。我將下面的代碼僅僅作爲一個例子,說明如果技術或體系結構的限制迫使你這樣做,那麼COULD可以做這樣的事情。但是,它只能作爲最後的手段使用。

我已經做了一些討厭的事情,涉及到使用布爾和循環來「捕獲」異步調用,但我不會真的推薦它作爲一個特別好的做法。儘管如此,如果你想要的話,就在這裏。

// name is the template identifier, template is the template contents, 
// data is the "context" of the template (its model), callback (optional) 
// is the method you want the rendered template passed to, cbContext 
// (optional) is the context in which you want the callback to execute 
asyncToSync = function (name, template, data, callback, cbContext) { 
    // Tracks if it's time to return or not 
    var finished = false; 
    // Gives us an exit condition in case of a problem 
    var maxLoops = 10000; 
    // Create a variable to store the return value 
    var outVal = 'Template rendering did not finish'; 
    // And the callback function to pass to dust 
    var dustCb = function (err, html) { 
     finished = true; 
     outVal = html; 
    } 
    var i = 0; 
    // We create this as a function so that increment goes to the bottom 
    // of the execution queue, giving dustCb a chance to execute before 
    // the counter hits max. 
    var incrementCounter = function() { 
     i += 1; 
    }; 
    // Compile, load, and render the template 
    var compiled = dust.compile(template, name); 
    dust.loadSource(compiled); 
    // Pass our callBack so the flag gets tripped and outVal gets set 
    dust.render(name, data, dustCb); 
    // count up to maxLoops 
    while(!finished && (i < maxLoops)) { 
     incrementCounter(); 
    } 
    // If a callback is defined, use it 
    if (callback) { 
     // If a callback context is defined, use it 
     return (cbContext) ? callback.call(cbContext, outVal) : callback(outVal); 
    } 
    // otherwise just return the rendered HTML 
    return outVal; 
} 
+0

)如果這是不好的做法,不要讓它成爲一個潛在的答案。 – Trevor 2013-04-18 00:24:59

+1

更何況這將阻止一切。 – Trevor 2013-04-18 00:28:07

+0

我不是在諷刺或試圖粗魯。如果你需要訴諸「討厭的東西」,那麼你應該重新考慮你的設計。順便說一下,這對促進不良做法也沒有幫助。獲得一些人的技能,男人。 – Trevor 2013-07-05 19:23:39