Ручки не заполняют таблицу
Я использую Handlebars (v 1.0.0), чтобы заполнить таблицу в HTML.
Однако каким-то образом он не заполняет таблицу, как я привык.
Вот мой шаблон:
{{#if users}}
<table>
{{#each users}}
<tr>
<td>{{username}}</td>
<td>{{email}}</td>
</tr>
{{/each}}
</table>
{{else}}
<h3>No users found!</h3>
{{/if}}
Итак, я нахожу пользователей, потому что я не вижу "Нет пользователей!" и когда я вызываю пустой объект, он показывает "Нет пользователей!".
Если я не использую таблицу и не распечатываю эти пользователи, как следующий пример. Имена пользователей и почтовый адрес будут отображаться в моем HTML.
{{#if users}}
{{#each users}}
{{username}}<br/>
{{email}}<br/>
{{/each}}
{{else}}
<h3>No users found!</h3>
{{/if}}
Вот как мой шаблон строится в javascript:
var htmlSource = $(data).html();
var template = Handlebars.compile(htmlSource);
var compiled = template(usersArray);
that.$el.html(compiled);
Теперь, когда я console.log скомпилированный объект, он уже не показывает таблицу.
Знаете ли вы, почему это не работает, и можете ли вы мне помочь?
EDIT:
Я только что проверил еще несколько и обнаружил, что данные будут отображаться в HTML, когда я не буду терять теги <table>
. Однако <tr>
и <td>
не будут отображаться в html. Отобразятся данные в нем.
ИЗМЕНИТЬ 2:
Я узнал, что это проблема jquery или javascript.
Когда я console.log htmlSource, шаблон HTML изменяется на это:
{{#if users}}
{{#each users}}
{{/each}}
{{else}}
<h3>No users found!</h3>
{{/if}}
<table><tr>
<td>{{username}}</td>
<td>{{email}}</td>
</tr></table>
Как видно, таблица перемещается за пределы оператора if.
Я пробовал другие версии jQuery (2.0.2, 2.0.3, 2.0.1, 1.10.2), но это не сработало.
Я попытался использовать innerXHTML script, но это работает так же, как jQuery.
Итак, я предполагаю, что это может быть проблема FireFox (хотя я пробовал 25 и 26), Chrome делает то же самое... может быть, что-то в EcmaScript??
Я скоро узнаю вас...
ИЗМЕНИТЬ 3:
Я создал html файл с html, который мне нужен. С помощью script я получаю конкретный раздел html, который мне нужен, и поместите его в переменную данных.
Теперь, когда консоль регистрирует данные (console.log(data)), нет ничего плохого.
Когда консоль регистрирует данные с помощью jQuery, html изменяется: console.log($ (data));
Кажется, что-то там происходит не так, но только при использовании табличных тегов.
Это что-то, что jQuery не может справиться? Я не знаю. Я знаю, как преодолеть эту проблему, используя тег script... Хотя я хотел бы загрузить это, используя require;)
P.S. nemesv благодарит вас за редактирование;)
Ответы
Ответ 1
Убедитесь, что вы выставляете свой шаблон в теге, чтобы браузер не пытался его разобрать.
<script type="x-template" id="the-tpl">
{{#if users}}
<table>
{{#each users}}
<tr>
<td>{{username}}</td>
<td>{{email}}</td>
</tr>
{{/each}}
</table>
{{else}}
<h3>No users found!</h3>
{{/if}}
</script>
Если в теге script нет атрибута type
, то парсер HTML найдет ошибку и попытается ее решить. Из ваших сведений об ошибках действительно выглядит так, как будто это имеет место здесь.
Использование require
Как вы отметили, вы загружаете с помощью Require, а не загружаете свой шаблон с помощью text! плагин: require("text!path/to/template.html")
Чтобы быть еще более привлекательным, вы можете делегировать всю сборку рулей в плагин для загрузки шаблонов дескрипторов, поэтому шаблоны предварительно скомпилированы внутри вашей сборки - это вероятно, лучший.
В любом случае, ваша проблема заключается в том, что ваш шаблон обрабатывается парсером HTML и нарушает содержимое вашего шаблона. Убедитесь, что вы загрузили его как "текст" через XMLHttpRequest или с требованием или внутри тега script, который был правильно введен.
Ответ 2
Решение Simon является правильным, и проблема обсуждается в различных комментариях.
Я просто кладу кусочки здесь.
поскольку @rescuecreative указал, что некоторые браузеры удаляют пустые теги <table>
, когда html вставлен в DOM.
Случай здесь немного похож. Браузеры плохо себя ведут, когда видят недопустимую разметку. но в этом случае это не из-за отсутствия tr, td внутри таблицы. его из-за дополнительных строк до tr в таблице.
Ваша проблема начинается здесь.
var htmlSource = $(data).html();
любой механизм загрузки, который вы используете, вы вставляете шаблон в DOM перед его компиляцией с помощью рулей.
Это то, что происходит при добавлении нескомпилированного шаблона в DOM.
{{#if users}} <!-- browser does not understand this and tries to print it as it is-->
<table> <!-- browser sees the table tag and immediately looks for child TR, tbody, thead -->
{{#each users}} <!-- but instead finds plain text and hence considers it as invalid markup -->
<tr> <!-- the same story is repeated again>
<td>{{username}}</td>
<td>{{email}}</td>
</tr>
{{/each}} <!-- such plain strings are taken out of table markup and placed before or after depending upon the browser, in case of chrome placed before the table -->
</table>
{{else}}
<h3>No users found!</h3>
{{/if}}
Вот как это делает хром -
{{#if users}}
{{#each users}}
{{/each}}
<table>
<tbody>
<tr>
<td>{{username}}</td>
<td>{{email}}</td>
</tr>
</tbody>
</table>
{{else}}
<h3>No users found!</h3>
{{/if}}
На данный момент у меня нет firefox. но я уверен, что firefox имеет свой собственный метод коррекции разметки.
после этого, когда вы вынимаете его из DOM с помощью jquery и компилируете
var htmlSource = $(data).html();
var template = Handlebars.compile(htmlSource);
он просто выведет этот
<table>
<tbody>
<tr>
<td>{{username}}</td>
<td>{{email}}</td>
</tr>
</tbody>
</table>
если вы хотите, вы можете сбросить его после компиляции, чтобы увидеть.
var compiled = template(usersArray);
console.log(compiled);
that.$el.html(compiled);
Это также объясняет, почему вы получаете имя пользователя и адрес электронной почты, когда вы разделяете разметку таблицы в исходном шаблоне.
Теперь, чтобы решить эту проблему, используйте текстовый плагин, как указал Саймон. или поместите шаблон в строку.
Я тоже использую requriejs с чем-то следующим
define([
'underscore', // you can replace this with handlebars
'text!path/to/template.html'
], function(_, Tmpl){
return _.template(Tmpl); //and handlebar pre-compilation here
});
таким образом вы также можете заменить этот модуль на предварительно скомпилированный шаблон в процессе сборки.