【问题标题】:Using Handlebars.js to iterate over a list of names使用 Handlebars.js 遍历名称列表
【发布时间】:2023-02-20 18:47:23
【问题描述】:

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

记者:

$(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


    【解决方案1】:

    您的 HTML 有一些问题。

    首先,您的结束选择标记 &lt;/select&gt; 位于您的模板脚本标记内。

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

    其次,&lt;div&gt; 元素不是 select &lt;select&gt; 元素的有效子元素。

    我不确定是否所有浏览器都以相同的方式处理这个无效标签,但我正在使用 Chrome 进行尝试,并且 Chrome 似乎在呈现时完全忽略了 &lt;div id="myForm"&gt;&lt;/div&gt;。因此,没有要添加模板函数生成的 html 的元素。 html 值应该是附加&lt;select&gt;

    为了清楚起见,我建议从 &lt;select&gt; 中取出模板 &lt;script&gt; 标签。这将使 HTML 更易于阅读,并将 &lt;select&gt; 菜单与模板清楚地分开。

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

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

    【讨论】:

      【解决方案2】:

      史蒂夫的回答非常好,他的小提琴也很好用。不过,我想添加一些 cmets 并简化结果:

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

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

      史蒂夫描述了发生(或错误)的其余部分......

      为了简单起见,我什至可能会在模板中添加整个&lt;select&gt;,这样您就需要减少对 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
      

      通过查看模板和代码,您可能会发现一切似乎都清晰简单,不再四处传播。

      这是史蒂夫的slightly changed fiddle

      【讨论】:

        猜你喜欢
        • 2014-06-12
        • 2015-03-01
        • 1970-01-01
        • 2012-08-09
        • 2017-06-03
        • 2019-06-25
        • 1970-01-01
        • 2018-11-03
        • 1970-01-01
        相关资源
        最近更新 更多