如何访问嵌套对象的键

3
我正在尝试从一个包含嵌套对象的数据文件中获取值。
我想为每个在EN对象下的条目创建一个标签。因此,我希望最终拥有一个"mail"标签、一个"quote"标签和一个"phone"标签。
在标签中,我要访问tabLabel和tabIcon的内容并将其放入标签中。
使用Object.Keys()可以看到字符串,但是当我尝试console.log它们时,我得到了undefined。
我编写了这个函数,但它没有起作用:
function generateLabel() {
  const keys = Object.keys(TabFormData.EN);
  for (let i = 0; i < keys; i += 1) {
    return `
      <div class="${ID}_tab-form__headerItemWrap">
        <label for="taLabel-here"><i class="tabIcon-here"></i></label>
      </div>
    `;
  }
}

这是数据:

const TabFormData = {
  EN: {
    mail: [
      {
        tabLabel: 'Email Our Team',
        tabIcon: 'fa fa-envelope',
      },
      {
        label: 'First Name',
        type: 'text',
        name: 'name',
        required: true,
        hint: 'Please, provide your Name.',
      },
      {
        label: 'Last Name',
        type: 'text',
        name: 'surname',
        required: true,
        hint: 'Please, provide your Last Name.',
      },
      {
        label: 'Email Address',
        type: 'email',
        name: 'email',
        required: true,
        hint: 'Please, provide a valid email.',
      },
      {
        label: 'Your Message',
        type: 'textarea',
        required: true,
        name: 'message',
        hint: 'Write us a message.',
        rows: 20,
        cols: 50,
      },
      {
        label: 'About You',
        required: true,
        select: [
          'Home use',
          'Business use',
          'Freelance, professional',
        ],
      },
    ],
    quote: [
      {
        tabLabel: 'Request a Quote',
        tabIcon: 'fa fa-file-invoice-dollar',
      },
      {
        label: 'First Name',
        type: 'text',
        name: 'name',
        required: true,
        hint: 'Please, provide your Name.',
      },
      {
        label: 'Last Name',
        type: 'text',
        name: 'surname',
        required: true,
        hint: 'Please, provide your Last Name.',
      },
      {
        label: 'Phone Number',
        type: 'number',
        name: 'telephone',
        required: true,
        hint: 'Please, provide a valid number',
      },
      {
        label: 'Email Address',
        type: 'email',
        name: 'email',
        required: false,
        hint: 'Please, provide a valid email.',
      },
      {
        label: 'Your Message',
        type: 'textarea',
        required: false,
        name: 'message',
        hint: 'Write us a message.',
        rows: 20,
        cols: 50,
      },
      {
        label: 'About You',
        required: true,
        select: [
          'Home use',
          'Business use',
          'Freelance, professional',
        ],
      },
    ],
    call: [
      {
        tabLabel: 'Call Me Back',
        tabIcon: 'fa fa-phone',
      },
      {
        label: 'First Name',
        type: 'text',
        name: 'name',
        required: true,
        hint: 'Please, provide your Name.',
      },
      {
        label: 'Last Name',
        type: 'text',
        name: 'surname',
        required: true,
        hint: 'Please, provide your Last Name.',
      },
      {
        label: 'Phone Number',
        type: 'number',
        name: 'telephone',
        required: true,
        hint: 'Please, provide a valid number',
      },
      {
        label: 'About You',
        required: true,
        select: [
          'Home use',
          'Business use',
          'Freelance, professional',
        ],
      },
    ],
  },
  IT: {

  },
};


可能是访问/处理(嵌套)对象、数组或JSON的重复问题。 - str
4个回答

2
您的问题在于循环。
在这里,您正在检查 i 是否小于数组对象,这不是您想要的。 您想将 i 与数组中的项目数量进行比较。
那么就应该变成这样: for (let i = 0; i < keys.length; i += 1) 您的字符串文字也是错误的,此处的ID是未定义的变量。我假设您想要键的名称。对于此问题,它应该变为: <div class="${keys[i]}_tab-form__headerItemWrap"> 此外,一旦从for循环中 return ,它将自动在第一次迭代时中断(这意味着您始终只会获得一个项目)。您可以先构建整个字符串然后再返回它。
这将使您的函数变成:
function generateLabel() {
  const keys = Object.keys(TabFormData.EN);
  var str = "";
  for (let i = 0; i < keys.length; i += 1) {
    str +=
      `<div class="${keys[i]}_tab-form__headerItemWrap">
        <label for="taLabel-here"><i class="tabIcon-here"></i></label>
      </div>
    `;
  }

  return str;
}

Here's a Fiddle.


0
假设您将TabFormData.EN分配给名为data的变量,并将TabFormData.EN的Object.keys结果分配给名为keys的变量,您可以使用以下方法:
  • ${keys[i]}来检索名称并将其附加到您的
    类名中,
  • ${data[keys[i]][0].tabLabel}来检索tabLabel属性值并将其附加到您的<label>标记中,以及
  • ${data[keys[i]][0].tabIcon}来检索tabIcon属性值并将其附加到您的<i>标记中。

您可以忽略<hr>标签、<button>标签和渲染的<div>标签,如果您愿意,只需检查下面代码片段中的对象属性引用即可。它们只是为了说明jsFiddle中的代码结果和下面的代码片段:

/* JavaScript */
var x = document.getElementById('abc');
var btn = document.getElementById('btn');

function generateLabel() {
  const data = TabFormData.EN;
  const keys = Object.keys(data);
  
  for (let i = 0; i < keys.length; i += 1) {
    x.innerHTML += `
     <hr>
          <div class="${keys[i]}_tab-form__headerItemWrap">
            <label for="${data[keys[i]][0].tabLabel}">
              <i class="${data[keys[i]][0].tabIcon}-here">
                  class of this div is ${keys[i]}_tab-form__headerItemWrap, label for this is ${data[keys[i]][0].tabLabel} and icon is ${data[keys[i]][0].tabIcon}
              </i>
            </label>
          </div>
        <hr>`
  }
}

btn.addEventListener('click', generateLabel);

const TabFormData = {
  EN: {
    mail: [
      {
        tabLabel: 'Email Our Team',
        tabIcon: 'fa fa-envelope',
      },
      {
        label: 'First Name',
        type: 'text',
        name: 'name',
        required: true,
        hint: 'Please, provide your Name.',
      },
      {
        label: 'Last Name',
        type: 'text',
        name: 'surname',
        required: true,
        hint: 'Please, provide your Last Name.',
      },
      {
        label: 'Email Address',
        type: 'email',
        name: 'email',
        required: true,
        hint: 'Please, provide a valid email.',
      },
      {
        label: 'Your Message',
        type: 'textarea',
        required: true,
        name: 'message',
        hint: 'Write us a message.',
        rows: 20,
        cols: 50,
      },
      {
        label: 'About You',
        required: true,
        select: [
          'Home use',
          'Business use',
          'Freelance, professional',
        ],
      },
    ],
    quote: [
      {
        tabLabel: 'Request a Quote',
        tabIcon: 'fa fa-file-invoice-dollar',
      },
      {
        label: 'First Name',
        type: 'text',
        name: 'name',
        required: true,
        hint: 'Please, provide your Name.',
      },
      {
        label: 'Last Name',
        type: 'text',
        name: 'surname',
        required: true,
        hint: 'Please, provide your Last Name.',
      },
      {
        label: 'Phone Number',
        type: 'number',
        name: 'telephone',
        required: true,
        hint: 'Please, provide a valid number',
      },
      {
        label: 'Email Address',
        type: 'email',
        name: 'email',
        required: false,
        hint: 'Please, provide a valid email.',
      },
      {
        label: 'Your Message',
        type: 'textarea',
        required: false,
        name: 'message',
        hint: 'Write us a message.',
        rows: 20,
        cols: 50,
      },
      {
        label: 'About You',
        required: true,
        select: [
          'Home use',
          'Business use',
          'Freelance, professional',
        ],
      },
    ],
    call: [
      {
        tabLabel: 'Call Me Back',
        tabIcon: 'fa fa-phone',
      },
      {
        label: 'First Name',
        type: 'text',
        name: 'name',
        required: true,
        hint: 'Please, provide your Name.',
      },
      {
        label: 'Last Name',
        type: 'text',
        name: 'surname',
        required: true,
        hint: 'Please, provide your Last Name.',
      },
      {
        label: 'Phone Number',
        type: 'number',
        name: 'telephone',
        required: true,
        hint: 'Please, provide a valid number',
      },
      {
        label: 'About You',
        required: true,
        select: [
          'Home use',
          'Business use',
          'Freelance, professional',
        ],
      },
    ],
  },
  IT: {

  },
};
/* CSS */
<!-- HTML -->

<button id="btn">
Click Me
</button>
<div id="abc"></div>


0

正如@Adriani6所报告的那样,您在循环中遇到了问题,但是为了真正回答您的问题,以下是访问嵌套对象的方法:

function generateLabel() {
    const keys = Object.keys(TabFormData.EN);
    for (let i = 0; i < keys.length; i += 1) {
        let currentTabObject = TabFormData.EN[keys[i]];
        console.log(currentTabObject[0].tabLabel);
        console.log(currentTabObject[0].tabIcon);
    }
}

0

如果我理解正确,您正在寻找类似于这样的内容:

let cb = (v) => `<div class="${v[0]}"><label for="${v[1][0]['tabLabel']}"><i class="${v[1][0]['tabIcon']}"></i></label></div>`
Object.entries(TabFormData['EN']).map(cb); 

Object.keys() 仅返回对象的键,但是您似乎也想访问值。因此,在您的情况下,建议使用 Object.entries()

我建议阅读下面的链接: https://javascript.info/keys-values-entries


谢谢,这正是我在寻找的内容。同时我也发现我导入数据的方式不对,应该使用 import { TabFormData } 而不是 import TabFormData - d0t_m
愉快的编码!如果这个解决方案适用于您,请点赞。 - Marios Simou

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接