请注意,在桌子外时,相同的把手 #each 会成功。 我的 jsfiddle 包含两个带边框的输出来证明这一点。
值得一提的是,如果 {{each}} 标签放置在表格之外,其他标签也可以使用。 如果重复复制表格,这当然会产生不良影响,但也许它有助于缩小问题的范围:
这看起来可能是 jQuery 或其他东西的问题......当你执行console.log(frag);
你会看到{{#each}}
帮助器甚至在尝试用把手编译它之前就被推到了表之外...
我更新了 jsfiddle 将模板放在<script type="text/x-handlebars-template"></script>
标签中,它似乎工作正常......
是的,我刚刚发现自己:
http://jsfiddle.net/cwYhN/10/
就其价值而言,我认为是浏览器丢弃了它认为无效的 html,而不是 jquery 缺陷。
是的,我不确定它是 jQuery 的东西还是 jQuery 调用的本机浏览器函数。 无论哪种方式,它都不喜欢tbody
和tr
之间的{{ }}
tr
。
如果车把以某种方式构建以在此约束内操作,那就太好了。 例如,能够将“每个”放在标签中,同时隐含理解它会迭代标签的内容。 我可能想象它看起来像:
<table>
<tbody handlebars="{{each}}">
... these get iterated ...
</tbody>
</table>
允许这样的事情会阻止浏览器剥离重要的 each 语句,并且它可以捎带它所属的结束标记 (/tbody)
正如你们已经提到的那样,HTML 解析器被把手标记混淆了,并将其作为您尝试转换为把手模板的 DOM 结构:
{{#each activity}}
{{/each}}
<table style="border:1px solid #ccc;">
<thead>
<tr><th>Month</th>
<th>Imps</th>
<th>Clicks</th>
<th>Spend</th>
</tr></thead>
<tbody><tr>
<th>{{month}}</th>
<td>{{impressions}}</td><td>{{clicks}}</td><td>{{spend}}</td>
</tr></tbody>
</table>
应该使用类似上面的脚本行为、javascript 字符串或预编译来解决这个问题。
关闭它,因为这个问题更多的是浏览器实现细节,而不是车把本身的错误。
浪费了半天才发现 {{#each}} 在表中不起作用。 如果在文档中简单地说明了这一点,那将非常有帮助。
如果正确加载,每个都可以在表格中完美运行。 你是如何加载模板的?
@preichelt您应该从脚本标签中加载把手,以防止浏览器弄乱表格中的 {{#each}}。 您可以阅读有关堆栈溢出的更多信息:
http://stackoverflow.com/questions/15386276/why-should-we-wrap-our-templates-inside-script-blocks
这个错误浪费了我两个小时的生命,现在是周六晚上 10:30,我在我的办公室工作只是为了解决这个错误,直到我发现这个问题和 [Official Block Doc]
(http://handlebarsjs.com/builtin_helpers.html) 对此一无所知。
如果不清楚,这不是车把的错,而是你不知道 HTML 是如何工作的: https: //html.spec.whatwg.org/multipage/syntax.html#an -introduction-to-error - 解析器中的处理和奇怪案例
那么,您认为尝试使用 Handlebarsjs 的每个人都应该对 HTML 解析器的工作原理有很好的了解? 如果不是,那么是_用户的错_,而不是文档清晰的错? 这个假设没有意义。 另一个沉重而复杂的模板引擎,Angularjs,使用Html兼容语法作为他们的模板语法,例如,如果我需要循环表,我可以使用
<tr ng-repeat="dto in tableData">
Angularjs 通过使用 Html 注释来保持循环的内部状态:
<!-- ngRepeat: column in row -->
<tr ng-repeat="dto in tableData">
Angualrjs 尝试尽可能尊重和遵循 Html 的语法,并成功避免假设。 但是 Handlebarsjs 的模板语法并没有,所以它向用户暴露了 Html 解析器问题。
如果您的开发人员无法解决您身边的问题,那么如果您真的关心您的项目和来自世界各地的用户,您就有责任告诉您的用户意识到这个问题。
无论如何,我将打开一个文档问题,因为_我相信我不是第一个遇到这个令人头疼的问题的人,也不会是最后一个。 _
Angular 在 DOM 中运行,所以它是 DOM 感知的。 Handlebars 只处理字符串,没有 DOM 的概念。
@profullstack :正如@stevenvachon所说,Handlebars 不适用于 HTML,而只能用于文本。 但这从文档中可能并不明显,因为所有示例都是 HTML。 它个人也使用它来生成降价...
如果您能告诉我,您在文档中需要什么样的文本,我很乐意添加它。 但是,一般使用说明(包括带有<script>
-tag 的部分已经在http://handlebarsjs.com/ 的主页上
@profullstack我知道你对“浪费时间”感到沮丧,但在我看来,你完全倒退了。
没有任何开源项目或贡献者对您负有任何责任。 像把手这样的工具是免费创建和维护的,几乎不需要感谢,试图让其他开发人员的生活更轻松。 如果您无法使用任何开源项目,那么您的工作需要多长时间?
我可以直接告诉你,以这样的语气来写评论会与预期的效果相反。 简单的胡萝卜与大棒,如果您希望有人为您做某事,请很好地提出要求,甚至更好地提出 PR 并自己做。
@ErisDS谢谢你的建议。 也许我的第一条评论太强烈了,但我完全同意你的说法:
to try to making other developers lives easier
为什么我放弃 Angularjs 来使用 Handlebarsjs? _因为我相信 Handlebarsjs 会让我的生活比 Angularjs 更轻松。_
那么,请在文档中添加一些注意事项,以帮助您的数千名开源用户避免潜在的问题,这违背了您“让其他开发人员生活更轻松”的意愿? 我想不是。
为了:
No open source project nor contributor has any duty to you.
对,是真的。 你可以开始一个开源项目然后放弃它,这完全可以。 但是当你的项目成长时,你会花更多的时间和精力在你的项目上,你更喜欢你的项目,你也想与世界分享。 这时候你会开始_关心你的用户_和_关心你的文档_。 Handlebarsjs 就在这个阶段,这不是一个小项目,它是一个流行的项目,被全世界的程序员使用,甚至在韩国,在中国等等。
据我所知,Github 上的大多数开源程序员都为他们的项目和他们的 README.md 文件感到自豪,并希望越来越多的人使用他们的工具和代码。
因此,如果:
@nknapp感谢您的回复。
也许我的第一条评论太强烈了,我为此和阅读我评论的人道歉。
乍一看,Handlebars 的工作原理就像_一个文本替换工具_,而且非常容易理解。 所以当我写这样的东西时:
{{#each myListData}}
<tr>{{name}}</tr>
{{/each}}
如果它只是简单的替换,我希望是这样的:
<tr>nameA</tr>
<tr>nameB</tr>
但是当遇到 HTML 时,它的行为有所不同,这是因为正如@stevenvachon亲切地指出的那样,这是因为 HTML 解析器的
所以我想在“每个块助手”部分下面只有一句话就足够了:
WARNING: please use script block when you try to use #each block inside table, due to the know issue of [How HTML parse works(thanks for <strong i="18">@stevenvachon</strong>'s reference](https://html.spec.whatwg.org/multipage/syntax.html#an-introduction-to-error-handling-and-strange-cases-in-the-parser)
如果你能分享你的意见,我真的很感激。 谢谢。
问题是,这与#each
-helper 无关。 您永远不应该将模板直接写入 HTML。 像这样的声明应该在主页面上,但问题是:你会在那里读到吗?
也许我们可以在登录页面上的示例下方发出像您一样的警告...
只是另一个注意事项:
我不会在生产中使用脚本块方法。 相反,我会使用 Webpack 或其他工具来预编译模板。
@nknapp是的,我想您的意见是对的:我们永远不应该将模板直接写入 HTML。 所以我想在登陆页面上,第一个“入门”部分应该使用脚本作为示例,在下面的灰色块中,我们可以更改
You **can** deliver a template to the browser by including it in a <script> tag.
到
You **should always** deliver a template to the browser by including it in a <script> tag.
我猜你的建议是:
**never** write a template directly into HTML
完全正确,应该放在登陆页面让大家关注这个,这样可以避免很多问题。 我想这是个好主意,你认为是吗?
但是,这种解释不起作用,因为他们可能会将其理解为:
<script type="text/x-handlebars">
{{#each list as |item|}}
<td>{{item}}</td>
{{/each}}
</script>
@stevenvachon是的,在您的示例中,仅将模板放入脚本中是不够的,也许我们需要添加更多有关使用模板的正确方法的注释,我们想听听您对此的建议。
也许:
对于大多数生产应用程序,您不会想要使用解析器和字符串模板。 查看预编译。
@stevenvachon感谢您的评论,我想如果我们将您的 HTML 解析器链接与您的评论放在一起会更好:
对于大多数生产应用程序,您不会想要使用解析器和字符串模板。 查看预编译。 如果您将模板直接用于 HTML,则存在一些已知问题,例如,由于HTML 解析器的工作方式,#each 块助手将无法在表格内
应该可以拆分成
<script>
-tag 示例下方将模板放在
<script>
-tag 中很重要。 不要将它直接放入 HTML 中,否则 HTML 解析器可能会修改它(例如,如果它包含一个 table )
请注意,不建议将此方法用于生产应用程序。 也可以预编译您的模板。 [...]
实际上,我个人不会再在浏览器中使用 Handlebars:还有许多其他框架(不仅是 Angular 和 React,还有 Vue 和 Ractive)。 这个视频很酷,并显示了问题...
我在服务器上使用 Handlebars 作为静态页面生成器,但对于浏览器渲染,我认为有更好的方法。
@nknapp我开始编写handlebars-html-parser用于通过 VDOM 将它带到浏览器,但它遇到了阻力。
@nknapp感谢您的回复。 您的意见包括:
@profullstack我不是这个项目的维护者。
我已经进行了更改。
@nknapp谢谢,我相信很多人会从你的改变中受益。
我知道这个问题已经很老了,但由于 Sendgrid 的电子邮件模板编辑器没有遵循这些最佳实践,我最近遇到了这个问题。 如果其他人因为这个原因从 Google 解决了这个问题,一个解决方法是将把手代码放在 HTML 注释中。
<table >
<tbody>
<!-- {{#each items}} -->
<tr>
<td>{{this.key}}</td>
<td>{{this.value}}</td>
</tr>
<!-- {{/each}} -->
</tbody>
</table>
产生以下输出
<table>
<tbody>
<!-- -->
<tr>
<td>my key</td>
<td>my value</td>
</tr>
<!-- -->
<!-- -->
<tr>
<td>my key 2</td>
<td>my value 2</td>
</tr>
<!-- -->
</tbody>
<table>
(注意:我没有直接用 Handlebars 验证过,只是在 Sendgrid 的模板编辑器上)
谢谢@gurpreetatwal 的提示。 你用 SendGrid 的那个花絮为我节省了今晚调试的时间!
@gurpreetatwal但为什么呢?
@Lazarencjusz为什么关于修复工作的原因或为什么 SendGrid 电子邮件模板编辑器无法正常工作?
你好! 当您使用 div 元素而不是表格时,将起作用。
还将所有表格元素重写为 div。
@gurpreetatwal的解决方案适用于我的 Mailchimp/Mandrills 车把模板。 谢谢你帮我省了很多麻烦!
最有用的评论
我知道这个问题已经很老了,但由于 Sendgrid 的电子邮件模板编辑器没有遵循这些最佳实践,我最近遇到了这个问题。 如果其他人因为这个原因从 Google 解决了这个问题,一个解决方法是将把手代码放在 HTML 注释中。
产生以下输出
(注意:我没有直接用 Handlebars 验证过,只是在 Sendgrid 的模板编辑器上)