如何将JSON响应绑定到网页上的按钮操作



我编写了Javascript代码,用于查询Tableau服务器API以运行作业。返回的作业显示在网页上,其中有一个与每个作业相关联的按钮,允许用户终止该特定作业。

如果只有一个作业在运行,脚本可以正常工作,但如果有多个作业正在运行,则所选的终止按钮将停止与您打算终止的作业不同的作业
网页的屏幕截图

我已经包含了整个代码链和JSON响应的示例以供参考。

来自服务器的JSON响应示例:

{
"pagination": {
"pageNumber": "1",
"pageSize": "100",
"totalAvailable": "2"
},
"backgroundJobs": {
"backgroundJob": [
{
"id": "d17901fe-7fc5-4c3c-95ff-7013102b56b0",
"status": "Pending",
"createdAt": "2021-04-02T16:08:09Z",
"priority": "0",
"jobType": "refresh_extracts"
},
{
"id": "e91ab533-8050-4341-8ac9-9f3429d03718",
"status": "Pending",
"createdAt": "2021-04-02T16:08:09Z",
"priority": "0",
"jobType": "refresh_extracts"
}
]
}
}
function getToken() {
fetch('https://tableau.bjc.org/api/3.4/auth/signin', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
"credentials": {
"name": "login",
"password": "Password",
"site": {
"contentUrl": "Default"
}
}
})
}).then(function (response) {
return response.json()
}).then(function (data) {
token = data.credentials.token;
siteId = data.credentials.site.id;
userId = data.credentials.user.id;
return data;
}
).then(function () {
return fetch('https://tableau.server/api/3.4/sites/' + siteId + '/jobs?filter=status:eq:InProgress&fields=_all_', {
method: 'get',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
"X-Tableau-Auth": token
},
}).then(function (response) {
return response.json()
}).then(function (data) {
jobs = [data];
if (jobs[0].backgroundJobs.backgroundJob.length == 0) {
var noJobs = document.createElement("H4");
noJobs.innerText = "There are no jobs in progress."
document.getElementById("bee-alert").appendChild(noJobs);
//document.body.appendChild(noJobs);
}
for (let i = 0; i < jobs[0].backgroundJobs.backgroundJob.length; i++) {
jobId = jobs[0].backgroundJobs.backgroundJob[i].id;
name = jobs[0].backgroundJobs.backgroundJob[i].title;
startTime = jobs[0].backgroundJobs.backgroundJob[i].startedAt;
status = jobs[0].backgroundJobs.backgroundJob[i].status;
jobType = jobs[0].backgroundJobs.backgroundJob[i].jobType;

//Grab the main table and assign it to variable
var $table = $('#bee-table');

//append a body to the table
var $tbody = $table.append('<tbody />').children('tbody');
// add row
$tbody.append('<tr />').children('tr:last')
.append('<td>' + name + '</td>')
.append('<td>' + jobId + '</td>')
.append('<td>' + startTime + '</td>')
.append('<td>' + status + '</td>')
.append('<td>' + jobType + '</td>')
.append('<td><button id="bee-btn" type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModalCenter">End This Job</button><div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true"><div class="modal-dialog modal-dialog-centered" role="document"><div class="modal-content"><div class="modal-header bg-danger"><h5 class="modal-title" id="exampleModalLongTitle" style="color:#ffffff;"><i class="fas fa-exclamation-triangle"></i> Stop Running Job</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button></div><div class="modal-body">Are you sure you want to stop this job from running?</div><div class="modal-footer"><button type="button" class="btn btn-outline-secondary" data-dismiss="modal">Cancel</button><button id="kill-btn" type="button" class="btn btn-danger" data-dismiss="modal">Stop Job</button></td> </div></div></div></div>');
//append all of the above elements to the table
$table.appendTo('#bee-table');

var btn = document.getElementById("kill-btn");
// btn.onclick = killFunction;
btn.onclick = function () {
killFunction();
pageRefresh();
};


function killFunction() {
return fetch('https://tableau.server/api/3.4/sites/' + siteId + '/jobs/' + jobId, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
"X-Tableau-Auth": token
},
}).then(function (response) {
console.log(response.status);
return response.json()
});

}
}
})
});
}

您可以将当前的解决方案简化为这个。

我所做的是将数据集(data-job-id(附加到终止按钮,然后将click侦听器附加到表体,然后使用end-background-job类名来确定按钮是否触发了单击。

const fakeResponse = {
pagination: { pageNumber: "1", pageSize: "100", totalAvailable: "2" },
backgroundJobs: {
backgroundJob: [
{
id: "d17901fe-7fc5-4c3c-95ff-7013102b56b0",
status: "Pending",
createdAt: "2021-04-02T16:08:09Z",
priority: "0",
jobType: "refresh_extracts"
},
{
id: "e91ab533-8050-4341-8ac9-9f3429d03718",
status: "Pending",
createdAt: "2021-04-02T16:08:09Z",
priority: "0",
jobType: "refresh_extracts"
}
]
}
};
document.addEventListener("DOMContentLoaded", function() {
const $table = document.getElementById('jobs-table');
const endBackgroundJobClassName = 'end-background-job';
// Do the API request here
const terminateJob = (jobId) => {
if(confirm(`Remove job ${jobId}`)) {
// simulate API call
setTimeout(() => document.getElementById(jobId).remove(), 500);
}
};
$table.addEventListener('click', e => {
const el = e.target;

if(Array.from(el.classList).includes(endBackgroundJobClassName)) {
terminateJob(el.dataset?.jobId);
}
});

const markup = fakeResponse.backgroundJobs.backgroundJob.reduce((rawHtml, job) => {

rawHtml += `
<tr id=${job.id}>
<th>Job name here</th>
<td>${job.id}</td>
<td>${job.createdAt}</td>
<td>${job.status}</td>
<td>${job.jobType}</td>
<td>
<button data-job-id="${job.id}" type="button" class="btn btn-warning ${endBackgroundJobClassName}">End this job</button>
</td>
</tr>
`;

return rawHtml;
}, '');
$table.insertAdjacentHTML('beforeend', markup);
});
<table class="table">
<thead>
<tr>
<th>Job Name</th>
<th>Job ID</th>
<th>Time Started</th>
<th>Current Status</th>
<th>Job Type</th>
<th>Action</th>
</tr>
</thead>
<tbody id="jobs-table">
</tbody>
</table>

最新更新