簡體   English   中英

我如何只呈現更新的統計數據 - websockets

[英]How do I only render the updated stat - websockets

現在整個 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();

統計數據.pug

body
h1 Cases by country
div#overview

因此,如果我只更新國家比利時,我只希望更改該統計數據。 現在一切似乎都重新加載

我的建議是在 sockets 中嚴格保持客戶端和服務器之間的數據通信。 這意味着當一個用戶更新 1 個值時,該值將被發送到服務器並存儲。 在服務器完成存儲該值后,該相同的值將被發送到所有其他客戶端。 這樣,您只需發送和接收已更改的部分,而無需在每次更改時下載所有內容。

我可能無法完全按照應有的方式編寫代碼,因為我對 Primus.js 的經驗有限,並且對您的后端知之甚少。

但我認為你的前端部分看起來像這樣。 在下面的示例中,我從click事件中刪除了fetch function。 而是將更改的數據發送到應該處理那些昂貴任務的服務器。

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事件並檢查數據 object 中的操作來確定要做什么,來執行與服務器上相同的技巧。

您需要一種方法來確定如何定位要更改的元素,您可以通過在與數據對應的元素上設置 id 屬性來做到這一點。 因此,例如,您想更改“比利時”段落,那么如果有辦法識別它,它就會派上用場。 我不會 go 太多,而只是創建一些簡單的東西可能會奏效。

在下面的 HTML 示例中,我為段落指定了一個 ID。 此 id 與您要更新的國家/地區值相同。 這是查找要更新的元素的唯一標識符。 或者甚至創建如果它不存在。

之后的 JavaScript 示例通過 sockets 從服務器接收數據並檢查操作。 這與我們發送到服務器的數據相同,但只是現在每個人都收到了,我們才對其進行處理。

我寫了一個 function 將更新 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}`;
  }
}

我希望這是您正在尋找的內容和/或對您嘗試創建的內容有所幫助。 我想再說一遍,這是它如何工作的一個例子,並且還沒有經過我的測試。

如果您有任何問題或我不清楚,請不要猶豫,問。

要在評論中詳細說明@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');

})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM