JSON 到 HTML:根据 JSON 字段值制作模板(仅限 ES6)

JSON to HTML: Make Templates depending on JSON field value (ES6 only)

我正在尝试使用 .map() 遍历嵌套的 JSON 对象并根据 JSON inputType: "value"。我想使用基于 三元运算符 的正确模板 (es6 模板文字) 并将正确的 HTML 标记为 DOM.

我已经走得很远了,但我 运行 遇到了 级别 6(表单模板)和 级别 7[ 的问题(输入模板)。谁能指出我正确的方向?

Codepen: https://codepen.io/oneezy/pen/GxENOr

JS(省略了完整的 javascript..请参阅 codepen

/* FORM (Level 6)
⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼ */
function formTEMPLATE(form) {
  return `
  ${form.map(function(form) {
    return `
      ${form.inputType['text'] ? textfieldTEMPLATE(form.inputType) : ''}
      ${form.inputType['select'] ? selectTEMPLATE(form.inputType) : ''}
      ${form.inputType['radio'] ? radioTEMPLATE(form.inputType) : ''}
      ${form.inputType['checkbox'] ? checkboxTEMPLATE(form.inputType) : ''}
    `}).join('')}`
}


/* ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ INPUT TEMPLATES ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ */


/* TEXTFIELDS (Level 7)
⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼ */
function textfieldTEMPLATE(text) {
  return `
    ${text.map(function(text) {
     return `
        <label>${text.labelText}</label>
        <input type="${text.inputType}" id="${text.inputId} name="${text.inputClass}">
    `}).join('')}`
}

/* SELECT MENU (Level 7)
⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼ */
function selectTEMPLATE(select) {
  return `
  <select class="select">
      ${select.map(function(select) {
       return `
          <option id="${select.inputID} name="${select.inputGROUP}" ${select.inputOPTION}">${select.inputLABEL}</option>
      `}).join('')}
  </select>`
}

/* RADIO (Level 7)
⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼ */
function radioTEMPLATE(radio) {
  return `
  <ul class="radio">
      ${radio.map(function(radio) {
       return `
        <li>
          <input type="${radio.inputTYPE}" id="${radio.inputID}" name="${radio.inputGROUP}" ${radio.inputOPTION}>
          <label for="${radio.inputID}">${radio.inputLABEL}</label>
        </li>
      `}).join('')}
  </ul>` 
}

/* CHECKBOX (Level 7)
⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼⎼ */
function checkboxTEMPLATE(checkbox) {
  return `
  <ul class="checkbox">
      ${checkbox.map(function(checkbox) {
       return `
        <li>
          <input type="${checkbox.inputTYPE}" id="${checkbox.inputID}" name="${checkbox.inputGROUP}" ${checkbox.inputOPTION}>
          <label for="${checkbox.inputID}">${checkbox.inputLABEL}</label>
        </li>
      `}).join('')}
  </ul>`
}

JSON(省略了完整的 json..请参阅 codepen

[
  {
    "appLabel": "App",
    "appFolders": [
      {
        "folderLabel": "Folder",
        "folderFiles": [
          {
            "fileLabel": "File",
            "fileSections": [
              {
                "sectionLabel": "Select Menu",
                "sectionGroups": [
                  {
                    "groupLabel": "Group",
                    "groupInputs": [
                      {
                        "labelText": "Select 1",
                        "inputType": "select",
                        "inputId": "select1",
                        "inputClass": "select-1",
                        "inputCollection": [
                          {
                            "collectionLabelText": "Option 1",
                            "collectionInputType": "select",
                            "collectionInputId": "option1",
                            "collectionInputClass": "option-1",
                            "collectionInputName": "select-name-1"
                          },

form.inputType['text'] ? textfieldTEMPLATE(form.inputType) : ''

这里的问题是 form.inputType 有一个字符串值.. text | select 等...但是该代码检查 form.inputType 是否有一个名为 text属性 ... 它没有。 ..

所以,也许你想要 form.inputType == 'text' ? textfieldTEMPLATE(form.inputType) : ''

然而,这只是解决了一个问题...另一个是您在 textfieldTEMPLATE 等内部所做的...对传入的 string[=49 执行 .map =] ...字符串没有映射方法

所以,你想改变如下:注意,*TEMPLATE 函数是用参数 form 调用的,而不是 form.inputType - 因为 form 是一个 object 具有创建元素的有用属性,而 form.inputType 是一个字符串,对您想要做的事情没有帮助

function formTEMPLATE(form) {
    return `${form.map(function(form) {
        return `
            ${form.inputType == 'text' ? textfieldTEMPLATE(form) : ''}
            ${form.inputType == 'select' ? selectTEMPLATE(form) : ''}
            ${form.inputType == 'radio' ? radioTEMPLATE(form) : ''}
            ${form.inputType == 'checkbox' ? checkboxTEMPLATE(form) : ''}
        `}
    ).join('')}`;
}

function textfieldTEMPLATE(text) {
    return `
        <label>${text.labelText}</label>
        <input type="${text.inputType}" id="${text.inputId} name="${text.inputClass}">
        <br />
    `;
}

function selectOptionTEMPLATE(options) {
    return options.inputCollection.map(function(option) {
        return `<option id="${option.collectionInputId} name="${option.collectionInputName}" ${option.collectionInputOption || ''}">${option.collectionLabelText}</option>`
    }).join('');
}

function selectTEMPLATE(select) {
    return `<select class="select">${selectOptionTEMPLATE(select)}</select>`;
}

function cbRadioTEMPLATE(x) {
    return x.inputCollection.map(function(input) {
        return `<li>
            <input type="${x.inputType}" id="${input.collectionInputId}" name="${input.collectionInputName}" ${input.collectionInputOption || ''}>
            <label for="${input.collectionInputId}">${input.collectionLabelText}</label>
        </li>`;
    }).join('');
}

function radioTEMPLATE(radio) {
    return `<ul class="radio">${cbRadioTEMPLATE(radio)}</ul>`;
}

function checkboxTEMPLATE(checkbox) {
    return `<ul class="checkbox">${cbRadioTEMPLATE(checkbox)}</ul>`;;
}

注意函数 function cbRadioTEMPLATE(x) - 因为复选框和单选按钮都使用该代码作为框的 "list" - DRY 代码 FTW :p

https://codepen.io/anon/pen/xWpqRw

查看它的工作情况

using arrow functions the above code can be simplified to

const formTEMPLATE = form => form.map(item => `
  ${item.inputType == "text" ? textfieldTEMPLATE(item) : ""}
  ${item.inputType == "select" ? selectTEMPLATE(item) : ""}
  ${item.inputType == "radio" ? radioTEMPLATE(item) : ""}
  ${item.inputType == "checkbox" ? checkboxTEMPLATE(item) : ""}
`).join("");

const textfieldTEMPLATE = text => `<label>${text.labelText}</label><input type="${text.inputType}" id="${text.inputId} name="${text.inputClass}"><br/>`;

const selectOptionTEMPLATE = options => options.inputCollection.map(option => `
  <option id="${option.collectionInputId} name="${option.collectionInputName}" ${option.collectionInputOption || ""}">${option.collectionLabelText}</option>
`).join("");

const selectTEMPLATE = select =>`<select class="select">${selectOptionTEMPLATE(select)}</select>`;

const cbRadioTEMPLATE = x => x.inputCollection.map(input => `
  <li><input type="${x.inputType}" id="${input.collectionInputId}" name="${input.collectionInputName}" ${input.collectionInputOption || ""}>
    <label for="${input.collectionInputId}">${input.collectionLabelText}</label>
  </li>
`).join("");

const radioTEMPLATE = radio => `<ul class="radio">${cbRadioTEMPLATE(radio)}</ul>`;

const checkboxTEMPLATE = checkbox =>`<ul class="checkbox">${cbRadioTEMPLATE(checkbox)}</ul>`;

另一个优化是

const typeMap = {
  text: textfieldTEMPLATE,
  select: selectTEMPLATE,
  radio: radioTEMPLATE,
  checkbox: checkboxTEMPLATE
};
const formTEMPLATE = form => form.map(item => `${typeMap[item.inputType](item)}`).join("");