现在整个 div 重新渲染,但我正在寻找一种仅重新渲染更新后的统计数据的方法
这些是我现在拥有的部分
updatestats.js
document.querySelector("#submit").addEventListener("click", function (e) {
let country = document.querySelector("#country").value
let numberCases = document.querySelector("#number").value
fetch(base_url + "/api/v1/stats/updatestats", {
method: "put",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
"country": country,
"numberCases": numberCases
})
}).catch(err => {
console.log(err);
})
primus.write({ "action": "update" })
统计.js
primus.on("data", (json) => {
if (json.action === "update") {
document.querySelector("#overview").innerHTML = ""
appendInfo()
}
})
function appendInfo() {
fetch(base_url + "/api/v1/stats", {
method: "get",
headers: {
'Content-Type': 'application/json'
},
}).then(response => {
return response.json();
}).then(json => {
json.data.stats.forEach(stat => {
let country = stat.country
let numberCases = stat.numberCases
let p = document.createElement('p')
let text = document.createTextNode(`${country}: ${numberCases}`)
p.appendChild(text)
let overview = document.querySelector("#overview")
overview.appendChild(p)
})
}).catch(err => {
console.log(err);
})
}
window.onload = appendInfo();
统计.pug
body
h1 Cases by country
div#overview
因此,如果我只更新国家/地区比利时,我只想更改该统计数据。现在一切似乎都重新加载了
最佳答案
我的建议的意思是将客户端和服务器之间的数据通信严格保留在套接字中。这意味着当一个用户在其端更新 1 个值时,该值将被发送到服务器并存储。服务器完成存储该值后,相同的值将被发送到所有其他客户端。这样,您只需发送和接收已更改的部分,而无需在每次更改时下载所有内容。
我可能无法完全按照应有的方式编写代码,因为我对 Primus.js 的经验有限,并且对您的后端知之甚少。
但我认为你的前端部分看起来像这样。在下面的示例中,我从 click
事件中删除了 fetch
函数。相反,将更改后的数据发送到应处理这些昂贵任务的服务器。
const countryElement = document.querySelector("#country");
const numberCasesElement = document.querySelector("#number");
const submitButton = document.querySelector("#submit");
submitButton.addEventListener("click", function (e) {
let data = {
action: 'update',
country: countryElement.value,
numberCases: numberCasesElement.value
};
primus.write(data);
});
现在服务器应该收到一条消息,表明其中一个客户端已更新了部分数据。并且应该对这些数据做一些事情,比如存储它并让其他客户端知道这条数据已经更新。
primus.on('data', data => {
const { action } = data;
if (action === 'update') {
// Function that saves the data that the socket received.
// saveData(data) for example.
// Send changed data to all clients.
primus.write(data);
}
});
服务器现在应该已经存储了更改并将更改广播给所有其他客户端。现在,您自己和其他人将收到已更改的数据,并且现在可以渲染它。那么回到前端。我们通过监听 data
事件并检查数据对象中的操作来确定要做什么,从而执行与服务器上相同的技巧。
您需要一种方法来确定如何定位要更改的元素,您可以通过在与数据相对应的元素上设置 id 属性来实现此目的。例如,您想要更改“比利时”段落,那么如果有一种方法可以识别它,它就会派上用场。我不会讨论太多,只是创建一些简单的东西就可以解决问题。
在下面的 HTML 示例中,我为段落指定了一个 id。此 ID 与您要更新的国家/地区值相同。这是查找要更新的元素的唯一标识符。或者甚至创建(如果不存在)。
之后的 JavaScript 示例通过套接字从服务器接收数据并检查操作。这与我们发送到服务器的数据相同,但直到现在每个人都收到后我们才用它做一些事情。
我编写了一个函数来更新 HTML 中的数据。它将检查 id 与国家/地区匹配的元素,并相应地更新 textContent
属性。这与使用 document.createTextNode
几乎相同,但步骤更少。
<div id="overview">
<p id="Belgium">Belgium: 120</p>
</div>
const overview = document.querySelector("#overview");
primus.on('data', data => {
const { action } = data;
if (action === 'update') {
updateInfo(data);
}
});
function updateInfo(data) {
const { country, numberCases } = data;
// Select existing element with country data.
const countryElement = overview.querySelector(`#${country}`);
// Check if the element is already there, if not, then create it.
// Otherwise update the values.
if (countryElement === null) {
const paragraph = document.createElement('p');
paragraph.id = country;
paragraph.textContent = `${country}: ${numberCases}`;
overview.append(paragraph);
} else {
countryElement.textContent = `${country}: ${numberCases}`;
}
}
我希望这就是您正在寻找的内容和/或对您尝试创建的内容有帮助。我想再说一遍,这是一个说明它如何工作的示例,尚未经过我的测试。
如果您有任何疑问或我不清楚,请随时提问。
关于javascript - 如何仅呈现更新后的统计数据 - websockets,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61339472/