Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何只渲染更新的stat-websockets_Javascript_Node.js_Websocket_Primus - Fatal编程技术网

Javascript 如何只渲染更新的stat-websockets

Javascript 如何只渲染更新的stat-websockets,javascript,node.js,websocket,primus,Javascript,Node.js,Websocket,Primus,现在整个div都重新渲染了,但是我正在寻找一种只重新渲染更新的统计数据的方法 这些是我现在所拥有的东西的一部分 updatestats.js document.querySelector("#submit").addEventListener("click", function (e) { let country = document.querySelector("#country").value let numberCases = document.querySelector("#number

现在整个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" })
stats.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();
帕格

body
h1 Cases by country
div#overview

因此,如果我只更新比利时这个国家,我只想改变这个统计数字。现在一切似乎都重新加载了

要详细说明@EmielZuurbier在评论中的建议,请尝试以下代码

//Client-side

primus.emit('data',data);

primus.on("dataUpdated", (json) => {

});

//Server-side

primus.on('data',data =>{

//process it here and then
//send it out again


primus.emit('dataUpdated','the data you want to send to the front end');

})

我的建议是将客户机和服务器之间的数据通信严格保持在套接字中。这意味着当一个用户在其端更新1个值时,该值将被发送到服务器并存储。服务器存储完值后,相同的值将发送到所有其他客户端。这样,您只发送和接收已更改的部件,而无需下载每次更改的所有内容

我可能无法准确地编写代码,因为我在Primus.js方面的经验有限,对您的后端了解甚少

但我认为你的前端部分会像这样。在下面的示例中,我已从
单击
事件中删除了
获取
函数。而是将更改后的数据发送到服务器,该服务器将处理这些昂贵的任务

const countryElement=document.querySelector(“#country”);
const numbercaselement=document.querySelector(“#number”);
const submitButton=document.querySelector(“提交”);
submitButton.addEventListener(“单击”,函数(e){
让数据={
操作:“更新”,
国家:countryElement.value,
numberCases:numbercaselement.value
};
写(数据);
});
现在服务器应该会收到一条消息,其中一个客户端已经更新了一些数据。应该对这些数据做些什么,比如存储数据,让其他客户知道这段数据已经更新

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);

  }
});
服务器现在应该已经存储了更改并将更改广播给所有其他客户端。现在,您自己和其他人将收到已更改的数据,现在可以对其进行渲染。回到前端。我们执行与服务器相同的技巧,监听
数据
事件,并检查数据对象中的操作以确定要执行的操作

您将需要一种方法来确定如何针对要更改的元素,您可以通过在与数据对应的元素上设置id属性来实现这一点。例如,如果你想更改“比利时”一段,那么如果有办法识别它,它就会派上用场。我不想说太多,只想创造一些简单的东西来达到目的

在下面的HTML示例中,我给了段落一个id。这个id与您要更新的国家值相同。这是查找要更新的元素的唯一标识符。如果不存在,甚至可以创建

之后的JavaScript示例通过套接字从服务器接收数据并检查操作。这与我们发送到服务器的数据相同,但只有在每个人都收到数据后,我们才对其进行处理

我已经编写了一个函数来更新HTML中的数据。它将检查id与国家匹配的元素,并相应地更新
textContent
属性。这与使用
document.createTextNode
几乎相同,但步骤较少


比利时:120

我希望这是您正在寻找的和/或对您正在尝试创建的内容有所帮助。我想再次指出,这是一个如何工作的例子,在我这方面还没有经过测试


如果您有任何问题或我不清楚,请随时提问。

您是否尝试过
event.preventDefault()
?它阻止页面在仅更新数据时重新加载。您可以使用WebSocket将更改后的数据发送到服务器,并从服务器将其传递到所有其他客户端,而不是使用fetch上载和下载数据。这样,每个人都只获得通过套接字更改的数据。从这里,将您已有的数据与新收到的数据进行比较,只更新更改的元素。@AvivLo我在上次添加的updatestats.js行下面有e.preventDefault()行here@EmielZuurbier你有没有一个例子或者别的什么,因为我得到了理论,但不知道如何将它添加到我的代码中
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}`;
  }
}