我有一个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
通过查看模板和代码,你可能会意识到一切似乎都是清晰和简单的,不再分散了。
这是史蒂夫的小提琴。