#javascript #html #json #dom #addeventlistener
#javascript #HTML #json #dom #addeventlistener
Вопрос:
В настоящее время я извлекаю данные, которые мне нужно добавить в таблицу 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
})
})
Приветствуется любая помощь.
Комментарии:
1. используйте jQuery, это очень просто, вы можете найти документацию и примеры по этой ссылке https://datatables.net/examples/data_sources/dom.html
2. Почему ваша
html
переменная string начинается с'<table>'
, если вы используетеquerySelector
для получения<tbody>
тега элемента? Еслиtable
это ссылка на<tbody>
, тоtable.append
должна быть указана строка типа<tr><td>...</td></tr>
Ответ №1:
Первая проблема заключается в том, что строка
let promise = getUsers({page=2, role:'admin'})
должно быть
let promise = getUsers({page:2, role:'admin'})
Во-вторых, appendChild
принимает не строку, а элемент DOM. В этом случае вместо этого используйте innerHTML.
В-третьих, вы используете querySelect для поиска '<tbody>'
элемента, поэтому начните построение внутренних html-тегов с '<tr>'
не '<table>'
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
это просто короткий способ заставить функцию обернуть возврат в обещание. await
это просто новый языковой способ разрешить встроенное обещание без необходимости использования .then((res) => {...})
. await
может использоваться только в async
функции.
Ответы на вопросы в комментариях. Я представляю это альтернативное решение, которое:
- Не использует
async
иawait
- издевается
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>
Комментарии:
1. Привет, Дуг, ты можешь объяснить изменение в функции getUsers? в настоящее время предполагается, что функция извлекает данные из локальной конечной точки, а затем возвращает json. Также я не понимаю изменения переменной promise.
2. также задан ли для функции параметр по умолчанию?
3. Ваш вопрос просто говорит о том, чего ожидать от
http://localhost:3000/users
конечной точки. Вместо того, чтобы пытаться реализовать эту конечную точку сервера, я просто издевался над сигнатурой … функцией, которая возвращает обещание, которое преобразуется в массив пользователей.4. Если по умолчанию используется param, вы имеете в виду, что я игнорирую значение параметра options, тогда да. Я просто заглушаю возвращаемое значение.
5. что касается переменной promise. Вы объявили это, но никогда не использовали. Вместо
async
иawait
ключевых слов для сокращения я мог бы сделатьlet promise = getUsers({page:2, role:'admin'});
, за которым следуетpromise.then(users => {...})
Ответ №2:
С помощью jQuery это сделать очень просто.
Возьмите этот фрагмент в качестве примера, в котором используется библиотека 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>
Он также предоставляет различные настройки и интеграции, которые, я уверен, вы найдете полезными.