2014-09-27 37 views
2

因此,我得到了一个很大的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}} 
+1

你为什么在2014年使用'onclick'属性? – 2014-09-27 23:44:36

回答

1

试图将事件绑定到的 “东西” 名单时,我上周也有类似的问题。我的哲学斗争导致我关于逻辑少自然胡须(和把手)的这样的回答:https://stackoverflow.com/a/4946409/365252

需要注意的是胡子是很重要的 - 设计 - 逻辑少。这是试图完成什么是 加剧 激励开发人员将逻辑与演示分开,即任何使您的演示标记“跳舞”或链接到“仅由标记无法表达的”“事物”应该远离您的模板。

但是回到我们的问题......真实的Eureka当我意识到我的问题不是“我如何将它与标记绑定”时,我立刻意识到了这一点。

我真正的问题是:“有明确涉及的环路和环路的项目之间的逻辑为什么我使用胡子遍历它们在逻辑较少的环境?”

那么拐弯抹角几分钟击败后,你可能想知道我的解决办法是:

这是我虚构的模板:

<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; 

和吞咽后,终于这一切库尔急救,明显的回味:我必须这样做绑定的事件,我宁愿只是把<script>标签我的模板里面!?

如果你问自己这个问题,也许逻辑较少模板不适合你。

声明:我一直在使用Handlebars /胡须不到一个月,我仍然发现自己问上述问题的某些用例。这不是Silver Bullet

+0

非常感谢!这是一个很好的解决方案,但它是在胡须/把手上面的js猴子补丁。必须有一个简单的方法来做到这一点,虽然我承认这是诀窍 – akiva 2014-09-27 23:05:05

+0

我也相信,可能有一个单线解决方案可用于所有这些,但我有一种感觉,它不涉及小胡子/把手。 – 2014-09-27 23:10:46

+0

我准备尝试使我的生活更轻松的任何其他模板语言。我将深入研究jquery模板的引用并让你知道 – akiva 2014-09-27 23:13:33

1

我发现(在车把上,但可能appliable也髭)做到这一点的方法如下:

  • 创建在JSON返回this对象助手(字符串化)
  • 创建一个函数解析JSON并返回对象
  • 从模板中调用该函数。

代码:

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)this对象您在browseToTopic函数内部找到的不是原始上下文的1:1副本,但它已被转换为JSON,然后再转换为对象。这意味着目标对象将缺少所有非原始对象(例如函数)。考虑这是否足以满足您的需求。

+0

无论'{{getThis}}返回的值是否应该被转义以适应属性(如引号和&符号),Mustache/Handlebars只会转义代码以用作标记。进一步假设它只包含可编码的数据(没有函数,引用,其他非原始类型) – 2014-09-27 22:39:59

+0

感谢您指出,它应该肯定会逃脱。另外,你是对的,它不会真的返回'this',而是它的一个副本,没有非原始类型或函数。我仍然认为这可能足以满足OP的需求,同时保持代码精简和可行。 – 2014-09-27 22:48:00

+0

感谢您的回复,但我对onclick =“_。bind(func,{as-long-as-hell-data-in-here})感到不舒服。我强烈希望改用一些引用(正如我在最初的问题) – akiva 2014-09-27 23:07:12