我有一个 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"
。因此,解析器看不到结束选择标记。
第二,
<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供您参考。
史蒂夫的回答非常好,他的小提琴也能正常工作。我想添加一些评论并简化结果:
关于结束标记
</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
只要看模板和代码,你就会发现一切似乎都简单明了,不再四处散布。
这里是史蒂夫的略微改变的小提琴