【问题标题】:Handlebars does not fill table车把没有填满桌子
【发布时间】:2013-12-16 14:32:52
【问题描述】:

我正在使用 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 编译的对象时,它还没有显示表格。

你知道为什么它不起作用吗?你能帮帮我吗?

编辑:

我刚刚测试了一些,发现当我省略&lt;table&gt; 标签时,数据会显示在 HTML 中。但是 &lt;tr&gt;&lt;td&gt; 不会出现在 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 脚本,但这与 jQuery 相同。

所以我的猜测是这可能是一个 FireFox 问题(尽管我尝试了 25 和 26),Chrome 也是如此......也许 EcmaScript 中的某些东西??

我会尽快通知你的……

编辑 3:

我用我需要的 html 创建了一个 html 文件。通过一个脚本,我得到了我需要的 html 的特定部分,并将其放在 data 变量中。

现在当控制台记录数据 (console.log(data)) 时没有任何问题。 当控制台使用 jQuery 记录数据时,html 被更改:console.log($(data));

那里似乎出了点问题……但仅限于使用表格标签时。 这是jQuery无法处理的事情吗?我不知道。我知道如何通过使用 script 标签来解决这个问题......虽然我想使用 require 来加载它;)

附: nemesv 感谢您的编辑;)

【问题讨论】:

  • 假设usersArray 看起来像{users: [...]},它似乎按预期工作jsfiddle.net/nikoshr/Rwg6y/1
  • 你用的是什么浏览器?
  • 多么奇怪。我正在使用 FireFox 25.0.1,文件数组确实看起来像这样。只是不知道为什么它不能与表格一起使用并且没有.. 并且在 jsfiddle 中它可以正常工作..
  • 我刚刚尝试使用更高版本的车把。还没有运气。
  • 你能编辑 nikoshr 的 jsfiddle 来重现你的问题吗?

标签: javascript jquery backbone.js handlebars.js


【解决方案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>

如果脚本标签上没有type 属性,HTML 解析器会发现一个错误并尝试解决它。从您的错误详细信息来看,这里确实是这种情况。

使用要求

正如您所说,您使用 Require 加载,而不是确保您使用 text! plugin 加载模板:require("text!path/to/template.html")

更棒的是,您可以将所有车把编译委托给 handlebars template loading plugin,以便在您的构建中预编译模板 - 这可能是最好的。

无论哪种方式,您的问题是您的模板被 HTML 解析器解析,这破坏了您的模板内容。确保通过 XMLHttpRequest 将其加载为“文本”,或者使用 require 或在正确键入的脚本标签内加载。

【讨论】:

  • 好吧,我没有为模板使用脚本标签。我用我需要的 html 创建了一个 html 文件。通过一个脚本,我得到了我需要的 html 部分,并将其放在数据可验证中。现在,当控制台记录数据时(console.log(data))没有任何问题。当控制台使用 jQuery 记录数据时,html 会改变:console.log($(data));
  • $(data) 将解析您的模板。您真的不希望 HTML 引擎解析您的模板。我在您询问的有关 Require.js 的问题中看到了,因此我在回答中添加了有关此问题的注释。但更基本的事情是让它与任何东西一起工作,让你的模板始终远离你的 HTML,它不能被 HTML 解析器解析和更改。
  • @BonifatiusK 在这行之前发生了什么var htmlSource = $(data).html(); 你正试图从 DOM 中获取你的模板。这意味着模板已经在 DOM 中并已解析。正如西蒙指出的那样。它不会工作。如果您正在使用一些脚本加载器。直接在js结构中加载模板。
【解决方案2】:

Simon 的解决方案是正确的,问题在各种 cmet 中都有讨论。 我只是把碎片放在这里。

正如@rescuecreative 指出的那样,当将html 插入DOM 时,一些浏览器会删除空的&lt;table&gt; 标签。

这里的情况有点类似。浏览器在看到无效标记时会出现异常行为。但在这种情况下,它不是因为缺少 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}}

这就是 chrome 的渲染方式 -

{{#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 有自己的标记校正方法。

之后,当您使用 jquery 将其从 DOM 中取出并编译时

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);

这也解释了为什么当您在原始模板中去除表格标记时会收到用户名和电子邮件。

现在要解决此问题,请使用 text plugin,正如 Simon 指出的那样。或将模板内联。

我也将 requriejs 与以下内容一起使用

define([
  'underscore',   // you can replace this with handlebars
  'text!path/to/template.html'
], function(_, Tmpl){
  return _.template(Tmpl);  //and handlebar pre-compilation here
});

这样,您还可以在构建过程中将此模块替换为预编译的模板。

【讨论】:

  • 感谢您提供浏览器如何呈现它的示例!
  • 请说明拒绝投票的原因,以便我改进。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-06
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多