Ручки не заполняют таблицу

Я использую 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
});

таким образом вы также можете заменить этот модуль на предварительно скомпилированный шаблон в процессе сборки.