Обратите внимание, что тот же дескриптор #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
.
Было бы неплохо, если бы рули каким-то образом работали в рамках этого ограничения. Например, возможность разместить «каждый» внутри тега, имея при этом неявное понимание того, что он выполняет итерацию по содержимому тега. Я могу представить, как это выглядит:
<table>
<tbody handlebars="{{each}}">
... these get iterated ...
</tbody>
</table>
Разрешение чего-то подобного не позволит браузеру исключить каждый важный оператор, и он может использовать закрывающий тег, которому он принадлежит (/ 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
Эта ошибка потратила впустую два часа моей жизни, и сейчас 22:30 в субботу, я работаю в своем офисе, чтобы решить эту ошибку, пока не найду эту проблему и [Официальный блок-документ]
(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>
уже есть на главной странице http://handlebarsjs.com/. Вот почему я не уверен, что вам здесь нужно.
@profullstack Я понимаю, что вы разочарованы «потерей времени», но, на мой взгляд, у вас все наоборот.
Ни один проект с открытым исходным кодом или участник не несет перед вами никаких обязательств. Такие инструменты, как рули, создаются и обслуживаются бесплатно и почти без благодарности, чтобы попытаться облегчить жизнь другим разработчикам. Если бы вы вообще не могли использовать какие-либо проекты с открытым исходным кодом, сколько бы времени заняла ваша работа?
Я могу сказать вам из первых рук, что написание комментариев таким тоном будет иметь противоположный желаемый эффект . Простой пряник против кнута, если вы хотите, чтобы кто-то что-то сделал для вас, попросите вежливо, а лучше поднять пиар и сделать это самостоятельно.
@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, он ведет себя по-другому, и это из-за естественного HTML-парсера, как любезно заметил @stevenvachon .
Думаю, под разделом «Помощник для каждого блока» будет достаточно всего одного предложения:
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, например, помощник блока #each не будет работать внутри таблиц из-за того, как работает синтаксический анализатор HTML.
Вероятно, его следует разделить на
<script>
-tagВажно, чтобы вы поместили шаблон внутри тега
<script>
. Не помещайте его в HTML напрямую, иначе HTML-парсер может его изменить (например, если он содержит таблицу )
Обратите внимание, что этот подход не рекомендуется для производственных приложений. Также возможно предварительно скомпилировать ваши шаблоны. [...]
На самом деле, я лично больше не стал бы использовать Handlebars в браузере: существует множество других фреймворков (не только Angular и React, но также Vue и Ractive). Это видео довольно крутое и показывает проблему ...
Я использую Handlebars на сервере и в качестве генератора статических страниц, но для рендеринга в браузере, я думаю, есть способы получше.
@nknapp Я начал писать -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)