【问题标题】:How to add JSON data to a HTML table如何将 JSON 数据添加到 HTML 表中
【发布时间】:2019-08-13 22:23:09
【问题描述】:

目前,我正在获取需要在收到 HTML 表格后添加到 HTML 表格中的数据。

我已经尝试了一些方法,但在页面加载后我无法动态添加数据。

我想使用 Javascript 或 jQuery 添加它

这是 HTML 结构:

<div>
    <table cellspacing="0" cellpadding="0">
        <thead>
          <tr>
            <th scope="col"><span>Email</span></th>
            <th><span>Last Name</span></th>
            <th><span>First Name</span></th>
            <th><span>Role</span></th>
            <th><span>Cell Phone User</span></th>
          </tr>
        </thead>
           <tbody>
              <tr>
                 <td scope="row" data-label="Email"></td>
                 <td data-label="Last Name"></td>
                 <td data-label="First Name"></td>
                 <td data-label="Role"></td>
                 <td data-label="Cell Phone User"></td>
               </tr>
           </tbody> 
    </table>
</div>

以下是获取数据后的示例:

[{
    "id": 1,
    "email": "janedoe@example.com",
    "familyName": "Doe",
    "givenName": "Jane",
    "role": "admin",
    "smsUser": true
  },
  {
    "id": 2,
    "email": "johndoe@example.com",
    "familyName": "Doe",
    "givenName": "John",
    "role": "standard",
    "smsUser": false
  }]

这是我迄今为止尝试过的:

这是我的事件监听器,用于在页面加载后加载数据:


window.path = "http://localhost:3000/users";

// getUsers function plus any additional functions go here ...
const getUsers = options => {
  let url = new URL(window.path);
  if (options) {
    url.search = new URLSearchParams(options)
  }
  return Promise.resolve(fetch(url))
}

document.addEventListener('DOMContentLoaded', () => {

 /* SELECT DOM ELEMENTS*/ 
let table = document.querySelector('tbody');

let promise = getUsers({page=2, role:'admin'})

.then(data => {

var html = '<table>';
for( var j in data[0] ) {
    html += '<th>' + j + '</th>';
 }
     html += '</tr>';

     for( var i = 0; i < data.length; i++) {
      html += '<tr>';
      for( var j in data[i] ) {
        html += '<td>' + data[i][j] + '</td>';
      }
     }
     html += '</table>';
     table.appendChild(html)

    return table;
  })
.catch(err => {
    console.log('Error fetching from /users', err);
    return null
  })

})



感谢任何帮助。

【问题讨论】:

  • 使用jQuery很简单,你可以在这个链接https://datatables.net/examples/data_sources/dom.html找到文档和例子
  • 如果您使用querySelector 获取&lt;tbody&gt; 元素标签,为什么您的html 变量字符串以'&lt;table&gt;' 开头?如果table 是对&lt;tbody&gt; 的引用,那么table.append 应该被赋予一个类似&lt;tr&gt;&lt;td&gt;...&lt;/td&gt;&lt;/tr&gt; 的字符串

标签: javascript html json dom addeventlistener


【解决方案1】:

第一个问题是那行

let promise = getUsers({page=2, role:'admin'})

应该是

let promise = getUsers({page:2, role:'admin'})

其次,appendChild 不需要字符串,它需要一个 DOM 元素。对于这种情况,请改用 innerHTML。

第三,您正在使用 querySelect 查找 '&lt;tbody&gt;' 元素,因此在 '&lt;tr&gt;' 而不是 '&lt;table&gt;' 开始构建内部 html 标记

const getUsers = async options => ([
  {
    id: 1,
    email: "janedoe@example.com",
    familyName: "Doe",
    givenName: "Jane",
    role: "admin",
    smsUser: true
  },
  {
    id: 2,
    email: "johndoe@example.com",
    familyName: "Doe",
    givenName: "John",
    role: "standard",
    smsUser: false
  }
]);
  
document.addEventListener('DOMContentLoaded', async () => {
  const table = document.querySelector('tbody');
  const users = await getUsers({ page:2, role:'admin' });
  const userToTableRow = user => [
  { attrs: 'scope="row" data-label="Email"', propName: 'email'},
  { attrs: 'data-label="Last Name"', propName: 'familyName'},
  { attrs: 'data-label="First Name"', propName: 'givenName'},
  { attrs: 'data-label="Role Name"', propName: 'role'},
  { attrs: 'data-label="Cell Phone User"', propName: 'smsUser'},
  ].map(mapper => (
    `<td ${mapper.attrs}>${user[mapper.propName]}</td>`
  )).join('');
  
  const html = users.map(user =>
    `<tr>${userToTableRow(user)}</tr>`
  ).join('');
  table.innerHTML = html;
});
<div>
  <table cellspacing="0" cellpadding="0">
    <thead>
      <tr>
        <th scope="col"><span>Email</span></th>
        <th><span>Last Name</span></th>
        <th><span>First Name</span></th>
        <th><span>Role</span></th>
        <th><span>Cell Phone User</span></th>
      </tr>
    </thead>
    <tbody>
    </tbody> 
  </table>
</div>

编辑: 我喜欢上面第一个实现中的 async/await。 async 只是强制函数将返回值包装在 Promise 中的一种简便方法。 await 只是一种无需使用.then((res) =&gt; {...}) 即可解决内联承诺的新语言方式。 await 只能在 async 函数中使用。

解决 cmets 中的问题。我提交了这个替代解决方案:

  • 不使用asyncawait
  • 模拟fetch 而不是getusers
  • 使用 document.createElement() 和 appendChild 而不是仅仅设置 innerHTML 内容。

const getUsersUrl = 'http://localhost:3000/users';

function mockFetch(url) {
  const stubbedResponse = JSON.stringify([
    {
      id: 1,
      email: "janedoe@example.com",
      familyName: "Doe",
      givenName: "Jane",
      role: "admin",
      smsUser: true
    },
    {
      id: 2,
      email: "johndoe@example.com",
      familyName: "Doe",
      givenName: "John",
      role: "standard",
      smsUser: false
    }
  ]);

  return Promise.resolve({
    json() {
      return Promise.resolve(JSON.parse(stubbedResponse));
    }
  });
}

const getUsers = options => {
  let url = new URL(getUsersUrl);
  if (options) {
    url.search = new URLSearchParams(options)
  }
  return mockFetch(url);
}

const userToTableRow = user => {
  const tr = document.createElement('tr');
  [
    {
      attrs: {
        scope: 'row',
        'data-label': 'Email'
      },
      propName: 'email'
    },
    {
      attrs: { 'data-label': 'Last Name' },
      propName: 'familyName'
    },
    {
      attrs: { 'data-label': 'First Name' },
      propName: 'givenName'
    },
    {
      attrs: { 'data-label': 'Role Name' },
      propName: 'role'
    },
    {
      attrs: { 'data-label': 'Cell Phone User' },
      propName: 'smsUser'
    },
  ].map(mapper => {
    const td = document.createElement('td');
    for (const [attrName, attrValue] of Object.entries(mapper.attrs)) {
      td.setAttribute(attrName, attrValue);
    }
    td.appendChild(document.createTextNode(user[mapper.propName]));
    return td;
  }).forEach(td => { tr.appendChild(td); });
  return tr;
}
  
document.addEventListener('DOMContentLoaded', () => {
  const table = document.querySelector('tbody');
  getUsers({ page:2, role:'admin' })
    .then(response => response.json())
    .then(users => {
      users
        .map(user => userToTableRow(user))
        .forEach(tr => { table.appendChild(tr); });
  });
});
<div>
  <table cellspacing="0" cellpadding="0">
    <thead>
      <tr>
        <th scope="col"><span>Email</span></th>
        <th><span>Last Name</span></th>
        <th><span>First Name</span></th>
        <th><span>Role</span></th>
        <th><span>Cell Phone User</span></th>
      </tr>
    </thead>
    <tbody>
    </tbody> 
  </table>
</div>

【讨论】:

  • 嗨,Doug,你能解释一下 getUsers 函数的变化吗?目前该函数假设从本地端点获取数据然后返回一个 json。我也不明白promise变量的变化。
  • 你也给函数一个默认参数吗?
  • 您的问题只是说明了对 http://localhost:3000/users 端点的期望。我没有尝试实现该服务器端点,而是模拟了签名......一个返回 Promise 的函数,该 Promise 解析为一组用户。
  • 如果默认参数,你的意思是我忽略了选项参数的值,那么是的。我只是删除了返回值。
  • 对于 promise 变量。您声明了它,但从未使用过它。而不是asyncawait 关键字作为速记,我可以先做let promise = getUsers({page:2, role:'admin'});,然后是promise.then(users =&gt; {...})
【解决方案2】:

使用 jQuery 非常简单。

以这个 sn-p 为例,它利用了jQuery DataTables 库。

$(document).ready(function() {
    $('#example').DataTable( {
        ajax: {
          url: "https://reqres.in/api/users",
          dataSrc: "data"
        },
        columns: [
            { "data": "id" },
            { "data": "first_name" },
            { "data": "last_name" }
        ]
    } );
} );
<link href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" rel="stylesheet" />
<table id="example" class="display" style="width:100%">
    <thead>
        <tr>
            <th>Id</th>
            <th>First Name </th>
            <th>Last Name</th>
        </tr>
    </thead>
</table>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>

它还提供了各种配置和集成,我相信您会发现它们很有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-21
    • 1970-01-01
    • 1970-01-01
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    • 2016-01-16
    • 2013-08-15
    相关资源
    最近更新 更多