Handlebars.js: Рули не работают в столах

Созданный на 15 авг. 2013  ·  37Комментарии  ·  Источник: handlebars-lang/handlebars.js

http://jsfiddle.net/cwYhN/3/

Обратите внимание, что тот же дескриптор #each успешно выполняется вне таблиц. В моем jsfiddle есть два вывода с рамкой, демонстрирующие это.

Самый полезный комментарий

Я знаю, что эта проблема довольно старая, но я столкнулся с ней недавно из-за того, что редактор шаблонов электронной почты 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)

Все 37 Комментарий

Как бы то ни было, если теги {{each}} размещены за пределами таблицы, другие теги будут работать. Это, конечно, имеет нежелательный эффект при многократном дублировании таблицы, но, возможно, помогает сузить проблему:

http://jsfiddle.net/cwYhN/6/

Похоже, это может быть проблема с jQuery или чем-то еще ... когда вы выполняете console.log(frag); вы видите, что помощник {{#each}} выталкивается за пределы таблицы еще до попытки скомпилировать его с помощью ручек ...

Я обновил jsfiddle, чтобы поместить шаблон в тег <script type="text/x-handlebars-template"></script> и, похоже, он работает нормально ...

http://jsfiddle.net/doowb/6GdPy/1/

Да, я только что сам это обнаружил:
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.

Вероятно, его следует разделить на

  1. Непосредственно под примером <script> -tag

Важно, чтобы вы поместили шаблон внутри тега <script> . Не помещайте его в HTML напрямую, иначе HTML-парсер может его изменить (например, если он содержит таблицу )

  1. Измените маркер о предварительной компиляции на.

Обратите внимание, что этот подход не рекомендуется для производственных приложений. Также возможно предварительно скомпилировать ваши шаблоны. [...]

На самом деле, я лично больше не стал бы использовать Handlebars в браузере: существует множество других фреймворков (не только Angular и React, но также Vue и Ractive). Это видео довольно крутое и показывает проблему ...

Я использую Handlebars на сервере и в качестве генератора статических страниц, но для рендеринга в браузере, я думаю, есть способы получше.

@nknapp Я начал писать -html-parser для использования в браузере через VDOM, но встретил сопротивление .

@nknapp Спасибо за ответ. Ваши комментарии включают:

  1. Важность размещения шаблона внутри

@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 для рулей. Спасибо, что избавили меня от множества проблем!

Была ли эта страница полезной?
0 / 5 - 0 рейтинги