上周我在尝试将事件绑定到“事物”列表时遇到了类似的问题。我的哲学斗争使我得到了关于 Mustache(和 Handlebars)的无逻辑性质的答案:https://stackoverflow.com/a/4946409/365252
请务必注意,Mustache 在设计上是 无逻辑。这样做的目的是agravate激励开发人员将逻辑与表示分离,即任何使您的表示标记“跳舞”或链接到仅用标记无法表达的“事物”的东西都应该保留远离你的模板。
但回到我们的问题......真正的尤里卡时刻来到我的脑海,我意识到我的问题不是“我如何将它与标记绑定”。
我真正的问题是:“循环和循环的项目之间显然涉及逻辑。为什么我要使用 Mustache 在无逻辑的环境中迭代它们?”
所以在拐弯抹角几分钟后,您可能想知道我的解决方案是什么:
这是我的虚构模板:
<h1>Argh these pesky topics!</h1>
{{{#topics}}} <!-- Note the 3 mustaches to avoid html escaping -->
这是我的行模板:
<button>Shiver me timber, I'm rusty ol' {{name}}</button>
然后所有的逻辑都用你的旧Javascript:
/* Important: Assuming you're using jQuery, if not you'll have to convert the render output from a string to a DOM Node first. jQuery is NOT necessary for this to work - I'm just trying to avoid innerHTML hacks */
var topics = [/* whatever topics are,*/],
topicsDOM = document.createDocumentFragment(),
$ = jQuery,
list,
i, t, row;
for (i = 0, t = topics.length; i < t; i++) {
row = $(Mustache.render(yourRowTemplate, topics[i]));
row.on('click', function () {
/* We know exactly what row this is via topics[i] so you can do anything you'd like here */
};
topicsDOM.appendChild(row);
}
/* Now... this bit I'm not very proud of and I'm hoping someone can point out a better solution */
list = $(Mustache.render(yourListTemplate, {
topics: '<ins class="no-collision-please">'}));
/* We're doing this because we want to preserve the decorated DOM Nodes,
Mustache expects plain markup as a string (our <ins>) */
list.find('ins.no-collision-please').replaceWith(topicsDOM);
/* Note that the <ins> never leaves our little sandbox nor does
it cause reflow/layouting since we're working inside a documentFragment (list) */
return list;
最后,在吞下所有这些 Kool-Aid 之后,明显的回味:我必须这样做才能绑定一个事件,我宁愿在我的模板中放一个 <script> 标记!?
如果您问过自己这个问题,也许 无逻辑 模板不适合您。
免责声明:我使用 Handlebars/Mustache 还不到一个月,但我仍然发现自己在针对某些用例提出上述问题。这不是Silver Bullet。