使用 Handlebars.js 遍历名称列表

问题描述 投票:0回答:2

我有一个 Bootstrap 选择下拉菜单,我正在尝试使用 Handlebars JS 将所需的选项输出到我的选择中,但它们没有出现。我在这里阅读了一些示例,所以不确定是什么阻止了我的代码正确呈现,任何指针将不胜感激。

HTML:

  <select class="custom-select" id="inputGroupSelect01" onChange="takeSelectedSourceValue(this);">
  <option id="source-language" value="" selected disabled>Auto</option>
  
  <div id="myForm"></div>
  <script type="text/handlebar-template" id="selectPersonTemplate">
  {{#each people}}
    <option value="{{valueLang}}">{{htmlLang}}</option>
  {{/each}}
  </select>
  </script>

 <script src="https://twitter.github.io/typeahead.js/js/handlebars.js"></script>

JS:

$(function () {
    // Define an array of people.
  var people = [
    { valueLang: 'DE', htmlLang: 'DE' },
    { valueLang: 'FR', htmlLang: 'FR' },
    { valueLang: 'IT', htmlLang: 'IT' },
    { valueLang: 'ES', htmlLang: 'ES' },
    { valueLang: 'SV', htmlLang: 'SV' },
    { valueLang: 'DA', htmlLang: 'DA' }
  ];
  
  // Get the text for the Handlebars template from the script element.
  var templateText = $("#selectPersonTemplate").html();
  
  // Compile the Handlebars template.
  var selectPersonTemplate = Handlebars.compile(templateText);
  
  // Evaluate the template with an array of people.
  var html = selectPersonTemplate({ people: people });
  
  // Take the HTML that was created with the Handlebars template and
  // set the HTML in the myForm div element.
  $("#myForm").html(html);
});
javascript html handlebars.js
2个回答
2
投票

您的 HTML 有一些问题。

首先,您的结束选择标签,

</select>
在您的模板脚本标签内。

HTML 解析器会忽略脚本标记中的内容,因为您已将脚本定义为

type="text/handlebar-template"
。因此,解析器看不到结束选择标记。

第二,

<div>
元素不是选择的有效子元素,
<select>
,元素。

我不确定是否所有浏览器都以相同的方式处理这个无效标签,但我正在使用 Chrome 进行尝试,Chrome 似乎在渲染时完全忽略了

<div id="myForm"></div>
。因此,没有要添加模板函数生成的
html
的元素。
html
值应appended
<select>
.

为了清楚起见,我建议从

<script>
中取出模板
<select>
标签。这将使 HTML 更易于阅读,并将
<select>
菜单与模板清楚地分开。

<select class="custom-select" id="inputGroupSelect01" onChange="takeSelectedSourceValue(this);">
  <option id="source-language" value="" selected disabled>Auto</option>
</select>
  
<script type="text/handlebar-template" id="selectPersonTemplate">
  {{#each people}}
    <option value="{{valueLang}}">{{htmlLang}}</option>
  {{/each}}
</script>

接下来,我们要确保将append

html
到我们的
#inputGroupSelect01
元素。

// append the HTML to the #inputGroupSelect01 select element.
$("#inputGroupSelect01").append(html);

我创建了一个fiddle供您参考。


0
投票

史蒂夫的回答非常好,他的小提琴也能正常工作。我想添加一些评论并简化结果:

关于结束标记

</select>
:每当您想使用 Handlebars 呈现的 HTML 扩展现有 HTML 时,您需要从 valid HTML 开始。在您的情况下,浏览器已经呈现“无效”
<select>
(无效,因为缺少结束标记)。大多数浏览器然后尝试通过添加结束标记来解决此问题,...但是您尝试使用您的模板添加另一个,但这是行不通的。我明白你为什么要这样做,因为你想在你的模板中“完成”
<select>
标签,但这已经太晚了,因为标签在你的模板有机会这样做之前就已经呈现了。

结论:在你的 javaScript 开始之前,HTML 已经呈现,即使它可能是无效的 HTML,所以你需要在操作 DOM 之前确保它是有效的。

其余的事情(或错误)由史蒂夫描述......

为了简单起见,我什至可能会在模板中添加整个

<select>
,这样您就需要减少对 HTMLElements 的引用并避免复杂性:

<script type="text/handlebar-template" id="selectPersonTemplate">
  <select class="custom-select" onChange="takeSelectedSourceValue(this);">
    <option id="source-language" value="" selected disabled>Auto</option>
    {{#each people}}
      <option value="{{valueLang}}">{{htmlLang}}</option>
    {{/each}}
  </select>
</script>

然后是 JS(只有来自小提琴的 JS 的一部分):

  // Get the template for Handlebars.
  // Put whole <select> inside template to keep things simple
  var template = $("#selectPersonTemplate");

  // Compile the Handlebars template.
  var selectPersonTemplate = Handlebars.compile(template.html());

  // Evaluate the template with an array of people.
  var html = selectPersonTemplate({ people: people });

  // Two ways of attaching the HTML to the DOM
  // $(html).insertAfter(template);
  template.replaceWith(html); // removes script at the same time

只要看模板和代码,你就会发现一切似乎都简单明了,不再四处散布。

这里是史蒂夫的略微改变的小提琴

© www.soinside.com 2019 - 2024. All rights reserved.