使用Handlebars.js遍历名称列表



我有一个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);
});

你的HTML有一些问题。

首先,你的关闭选择标签,</select>是在你的模板脚本标签。

脚本标记中的内容将被HTML解析器忽略,因为您已将脚本定义为type="text/handlebar-template"。因此,解析器不会看到关闭select标记。

第二,<div>元素不是select,<select>,元素的有效子元素。

我不确定是否所有浏览器都以同样的方式处理此无效标签,但我正在尝试使用Chrome,似乎Chrome在渲染时完全忽略了<div id="myForm"></div>。因此,没有可以添加模板函数生成的html的元素。html的值应该是<select>后面加上

我建议从<select>中取出模板<script>标签,只是为了清晰。这将使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>

接下来,我们要确保html附加到#inputGroupSelect01元素。

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

我已经创建了一个小提琴供您参考。

Steve的回答非常好,他的小提琴也很好。我想添加一些注释并简化结果:

关于结束标记</select>:每当您想用Handlebars呈现的HTML扩展现有的HTML时,您需要从有效的开始超文本标记语言在您的情况下,浏览器已经呈现了"无效";<select>(无效,因为缺少结束标记)。大多数浏览器试图通过添加结束标签来解决这个问题,…但是对于你的模板,你试图添加另一个,这不起作用。我能理解你为什么这么做,因为你想要"完成"。在你的模板中添加<select>标签,但是这已经太晚了,因为在你的模板有机会这样做之前标签已经呈现了。

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

接下来发生的事情(或错误)是由Steve描述的…

为了保持简单,我甚至可能会在模板中添加整个<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

通过查看模板和代码,你可能会意识到一切似乎都是清晰和简单的,不再分散了。

这是史蒂夫的小提琴。

最新更新