首页 > 解决方案 > 创建带有小胡子的动态下拉列表

问题描述

我有以下结构:

[
 "key 1": [ "val1", "val2", "val3" ],
 "key 2": [
  "key 3": [ "val4" ],
  "key 4": [ "val5" ]
 ]
]

我想从中生成下拉列表。“key 1”...将是可选名称,“val1”...值。如果所选键上有一个子数组,我想用这些值动态创建另一个下拉列表,直到子数组只有一个值。(例如“key 2”)

我不知道如何留胡子。我可以将第一级的所有键放入一个平面数组中,Object.keys但我什至无法生成第一个下拉列表。更不用说我知道如何与另一部分一起去。

最好能得到一个关于如何完成的大方向。

这是一些示例代码:

  const view = {
    files: getFiles(),
    "keys": function() {
      return Object.keys(this);
    }
  };

    <form>
      <select id="selector">
        <option>choose...</option>
        {{#files}}
          {{#keys}}
          <option value="">{{.}}</option>
          {{/keys}}
        {{/files}}
      </select>
    </form>

这是一个线框,顶部是选择时的第一种情况key1,底部是选择时的情况key2在此处输入图像描述

标签: javascriptmustache

解决方案


Mustache是一种logic-less模板语法,因为没有 if 语句、else 子句或 for 循环。相反,只有标签。一些标签被替换为一个值,一些什么都没有,而另一些则是一系列值。

因此,您无法使用 . 根据所选值更新呈现的 HTML mustache

在这里,我使用onchange事件根据先前选择的值使用没有mustache模板的纯 Javascript 动态创建选择

var data = {
  "key 1": ["val1", "val2", "val3"],
  "key 2": {
    "key 3": ["val4"],
    "key 4": ["val5"]
  }
}

function renderSelect(obj) {
  var array = Array.isArray(obj) ? obj : Object.keys(obj)
  var options = ['Choose', ...array].map(i => "<option>" + i + "</option>").join('')

  var select = document.createElement('select')
  select.innerHTML = options
  if (!Array.isArray(obj)) {
    select.onchange = function() {
      // remove next siblings
      var sib = [], el = this
      while (el = el.nextElementSibling) sib.push(el)
      sib.forEach(el => el.remove())
      // render select based on value
      renderSelect(obj[this.value])
    }
  }

  document.querySelector('form').insertAdjacentElement('beforeend', select);
}

renderSelect(data)
<form></form>


推荐阅读