所以我得到了一个大型JSON,其中包含许多嵌入主题的项目,我使用mustache.js从每个主题创建一个按钮。现在我想将子对象的引用绑定到每个按钮,以便它的onClick()不必执行繁重的查找,也不必将大量数据粘贴到按钮的事件中。
这可以用胡子或其他模板语言来完成吗?
JSON:
myJson={
"topics": [
{
"name":"topic 1",
"id":1,
"items":[
"name":"a great item",
"data": {...}
]
},
...
}
模板:
{{#topics}}
<button onClick="_.bind(browseToTopic,{{this}})">{{name}}</button>
{{/topics}}
答案 0 :(得分:1)
上周我尝试将事件绑定到“事物”列表时遇到了类似的问题。我的哲学斗争引导我得到关于小胡子(和把手)逻辑少性质的答案:https://stackoverflow.com/a/4946409/365252
值得注意的是,Mustache是 - 按设计 - 逻辑少。这要做的是加剧激励开发人员将逻辑与表示分离,即任何使你的演示标记“跳舞”或链接到单独用标记无法表达的“事物”的东西应该保持不变地狱远离你的模板。
但回到我们的问题......当我意识到我的问题不是“如何用标记绑定”时,真正的 Eureka 时刻来到我身边。
我真正的问题是:“循环与循环项目之间存在明显的逻辑关系。为什么我使用 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 / Moustache不到一个月,我仍然发现自己在某些用例中询问上述问题。这不是Silver Bullet。
答案 1 :(得分:1)
我发现(在把手中,但可能也适用于Mustache)的方法如下:
this
对象的帮助器
代码:
Handlebars.registerHelper('getThis', function() {
return JSON.stringify(this);
});
browseToTopic = function(obj){
console.log(JSON.parse(obj));
// do other stuff..
}
HTML /模板:
{{#topics}}
<button onClick="_.bind(browseToTopic,{{getThis}})">{{name}}</button>
{{/topics}}
在此处查看示例(不同的名称,但操作相同):http://jsfiddle.net/awhb772m/
更新:添加了一个与初始代码更相似的示例:http://jsfiddle.net/fbL7xjet/
请考虑到:
1)您的对象格式不正确。以下部分:
"items":[
"name":"a great item",
"data": {...}
]
应该是:
"items":[
{
"name":"a great item",
"data": {...}
}
]
2)我写的代码只是一个概念证明,你可能想要改进getThis
助手来逃避字符串化的JSON;
3)您在browseToTopic函数中找到的this
对象不是原始上下文的1:1副本,但它已转换为JSON,然后再转换为对象。这意味着目标对象将缺少所有非原始对象(例如,函数)。考虑一下这是否足以满足您的需求。