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("");
我正在尝试使用 .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("");