我正在尝试为即将进行的项目选择一个 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
实际上呈现节点将被修改的模板。
从用户的 Angular 来看,这显然不太好。
那么情况真的是这样吗(不能强制 dust.js
同步),如果是的话 - 如何应对?我应该使用同步引擎吗,比如 handlebars
或 mustache
或者我在这里没有看到明显的东西?
我们非常欢迎任何帮助、见解或建议。 谢谢! :)
编辑:
这个问题不是关于如何呈现模板,而是关于如何确保它在 fnRowCallback
之前呈现。完成。感谢@robertklep 用你的(已删除的)答案指出这一点。
最佳答案
编辑:明确地说,我认为这是一种不好的做法,您通常不应该这样做。我将下面的代码包含在内只是作为一个示例,说明如果技术或体系结构限制强加于您,您可以如何做这样的事情。但是,它只能作为最后的手段使用。
我过去做过一些令人讨厌的事情,涉及使用 bool 值和循环来“捕获”异步调用,但我不会真正推荐它作为一种特别好的做法。不过,如果您想要它,就在这里。
// 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;
}
关于javascript - 在同步回调中使用 dust.js(异步),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15908072/