Spring项目中如何局部刷新表单/fieldset,解决删除后视图更新问题
问题描述
我在Spring项目中有一个index.html文件,包含两个表单。第一个表单输入姓名并提交后,姓名会传递到第二个表单,该表单关联数据库并在fieldset中展示数据。目前两个按钮的情况:
- ADD to DB:点击添加条目后可立即看到新增项,功能正常
- DELETE an item from DB by ID:能正常删除数据库中的条目,但视图不会刷新,需整页刷新才能看到结果,而整页刷新会回到第一个表单页面。我需要修改DELETE函数,实现仅刷新表单或fieldset而非整页。
原代码如下:
<!DOCTYPE html> <html lang="en" xmlns:https="http://www.w3.org/1999/xhtml" xmlns:http="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>SHOPPING LIST</title> <link rel="stylesheet" href="https://unpkg.com/purecss@1.0.0/build/pure-min.css" integrity="sha384-nn4HPE8lTHyVtfCBi5yW9d20FjT8BJwUXyWZT9InLYax14RDjBj46LmSztkmNP9w" crossorigin="anonymous"> </head> <body> <main style="width: 40%; margin: 0 auto"> <div id="welcome" style="text-align: center"> <h1>Introduce yourself</h1> </div> <form id="welcomeForm" class="pure-form pure-g pure-form-aligned"> <input class="pure-input-rounded pure-u-1" name="name" placeholder="name" id="text_name"> <button id="welcomeFormBtn" class="pure-button pure-button-primary pure-u-1">Submit</button> </form> <form id="AddForm" class="pure-form" style="text-align: center; display: none"> <fieldset> <input id="name" class="pure-input-rounded pure-input-2-3" style="width: available" placeholder="name"> <input id="amount" class="pure-input-rounded pure-input-2-3" style="width: available" placeholder="amount"> <input id="uom" class="pure-input-rounded pure-input-2-3" style="width: available" placeholder="unit of measure"> <input id="idToDel" type="number" class="pure-input-rounded pure-input-2-3" style="width: available" placeholder="Please provide an id to delete"> </fieldset> <fieldset> <button id="addProduct" class="pure-button pure-button-primary">POST</button> <button id="delProduct" class="pure-button pure-button-primary">DELETE</button> <br> <button id="print-btn" style="width: 50px; height: 50px; border-radius: 50%"><img style="width: 40px; height: 40px" src="https://cdn-icons-png.flaticon.com/512/3233/3233446.png" alt="PRINT"></button> </fieldset> <fieldset id="allProducts" > </fieldset> </form > </main> <script> const API_URL = 'http://localhost:8080'; const API_URL_ADD = `${API_URL}/api`; const API_URL_ALL = `${API_URL_ADD}/list`; const pName = document.getElementById('name'); const pUom = document.getElementById('uom'); const pAmount = document.getElementById('amount'); AddFunction(); fetch(API_URL_ALL) .then(processOkResponse) .then(list => list.forEach(createNewProduct)) document.getElementById('addProduct').addEventListener('click', (event) => { event.preventDefault(); fetch(API_URL_ALL, { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ name: pName.value, type : pUom.value, amount: pAmount.value }) }) .then(processOkResponse) .then(createNewProduct) .then(() => pName.value = '') .then(() => pAmount.value = '') .then(() => pUom.value = '') .catch(console.warn); }); function createNewProduct(product) { const label = document.createElement('label'); const l1 = document.createElement('label'); const l2 = document.createElement('label'); const l3 = document.createElement('label'); const l4 = document.createElement('label'); label.classList.add('label'); l1.appendChild(document.createTextNode(` ID:${product.id}. `)); l2.appendChild(document.createTextNode(` ${product.name} `)); l3.appendChild(document.createTextNode(` ${product.amount} `)); l4.appendChild(document.createTextNode(` ${product.type} `)); label.appendChild(l1).appendChild(l2).appendChild(l3).appendChild(l4) document.getElementById('allProducts').appendChild(label); label.style.display= 'table'; label.style.paddingLeft='40%'; label.style.wordSpacing='30%'; } document.getElementById('delProduct').addEventListener('click', (event) => { event.preventDefault(); removeTodo(); }); function removeTodo() { const d = document.getElementById('idToDel').value; fetch(`${API_URL_ALL}/${d}`, { method: 'DELETE' }) .then(processOkResponse) .catch(console.info) } function AddFunction(){ const welcomeForm = document.getElementById('welcomeForm'); document.getElementById('welcomeFormBtn').addEventListener('click', (event) => { event.preventDefault(); const formObj = { name: welcomeForm.elements.name.value, }; fetch(`${API_URL_ADD}?${new URLSearchParams(formObj)}`) .then(response => response.text()) .then((text) => { document.getElementById('welcome').innerHTML = ` <h1>${text}</h1> `; welcomeForm.remove(); document.getElementById('AddForm').style.display = 'block'; }); }); } document.getElementById('print-btn').addEventListener('click', (event) => { event.preventDefault(); const f = document.getElementById("allProducts").innerHTML; const a = window.open(); a.document.write(document.getElementById('welcome').innerHTML); a.document.write(f); a.print(); }) function processOkResponse(response = {}) { if (response.ok) { return response.json(); } throw new Error(`Status not 200 (${response.status})`); } </script> </body> </html>
解决方案
下面提供两种可行的修改方案,任选其一即可解决问题:
方案一:删除后直接移除对应DOM元素(高效)
修改removeTodo函数,在删除成功后找到对应ID的元素并从页面移除:
function removeTodo() { const d = document.getElementById('idToDel').value; fetch(`${API_URL_ALL}/${d}`, { method: 'DELETE' }) .then(processOkResponse) .then(() => { // 清空删除ID输入框 document.getElementById('idToDel').value = ''; // 找到包含目标ID的标签并移除 const productLabels = document.querySelectorAll('#allProducts .label'); productLabels.forEach(label => { if (label.textContent.includes(`ID:${d}.`)) { label.remove(); } }); }) .catch(console.info) }
说明:这种方式不用重新请求接口,直接操作DOM更新视图,响应更快,适合数据一致性要求不高的场景。
方案二:删除后重新请求最新数据并渲染(数据同步性高)
如果希望视图和数据库数据完全同步,可选择删除成功后重新获取全部数据并渲染:
function removeTodo() { const d = document.getElementById('idToDel').value; fetch(`${API_URL_ALL}/${d}`, { method: 'DELETE' }) .then(processOkResponse) .then(() => { // 清空删除ID输入框 document.getElementById('idToDel').value = ''; // 清空当前展示的所有产品 const allProductsContainer = document.getElementById('allProducts'); allProductsContainer.innerHTML = ''; // 重新请求最新数据并渲染 return fetch(API_URL_ALL); }) .then(processOkResponse) .then(list => list.forEach(createNewProduct)) .catch(console.info) }
说明:这种方式会重新拉取数据库中的最新列表,确保视图数据和数据库完全一致,适合多用户操作或数据频繁变更的场景。
内容的提问来源于stack exchange,提问作者Jumperro
相关产品推荐
相关产品推荐

