ASP.NET Core中点击新增地址按钮时如何防止已填数据清空?
解决动态新增地址字段时已填数据丢失的问题
你当前的ASP.NET Core注册表单中,点击「Add Address」新增地址字段时,已填写的第一个地址数据会被清空,核心原因和修复方案如下:
问题根源
- 使用
innerHTML +=操作DOM时,浏览器会先将容器内现有元素转换为HTML字符串,拼接新内容后重新解析成DOM元素。这个过程会销毁原有输入元素,导致用户输入的内容丢失。 - 删除按钮的ID未绑定索引,多个按钮共用同一个ID
btnRemove,会导致删除功能异常。
修复方案
- 用
insertAdjacentHTML('beforeend', fieldHtml)替代innerHTML +=,直接在容器末尾追加新DOM元素,不影响现有元素状态。 - 给删除按钮的ID加上索引,保证每个按钮ID唯一。
- 将单个地址的所有列包裹在一个
.row容器内,删除时直接移除整个地址行,简化逻辑。 - 补充表单控件的
name属性,确保提交时能正确绑定到模型集合。
修改后的完整代码
@model Registration @{ ViewData["Title"] = "Register Page - Step Two"; } <button type="button" class="btn btn-primary" onclick="addAddress()">Add Address</button> <div class="container mt-5"> <div class="row"> <div class="col-md-12"> <h2 class="text-center mb-4">Address Details</h2> <form asp-page-handler="RegisterStepTwo" method="post"> <div id="addressesContainer" class="mt-3"> <!-- Addresses will be dynamically added here --> </div> <button type="submit" class="btn btn-primary w-100">Next</button> </form> </div> </div> </div> @section Scripts { <script> let addressCount = 0; function addAddress() { addressCount++; const addressesContainer = document.getElementById('addressesContainer'); // 将单个地址的所有列包裹在row容器中,方便后续删除 const fieldHtml = ` <div class="row fieldRow" id="addressRow${addressCount}"> <div class="col-md-2 mb-3" id="type${addressCount}"> <label class="form-label">Address type</label> <select id="addressType${addressCount}" class="form-select" name="Addresses[${addressCount-1}].Type"> <option value="">Select Address Type</option> <option value="Permanent">Permanent</option> <option value="Present">Present</option> </select> </div> <div class="col-md-3 mb-3" id="housenumber${addressCount}"> <label class="form-label">House No.</label> <input type="text" id="houseNumberVisible${addressCount}" class="form-control" placeholder="Enter house number" name="Addresses[${addressCount-1}].HouseNumber"> </div> <div class="col-md-3 mb-3" id="street${addressCount}"> <label class="form-label">Street</label> <input type="text" id="streetVisible${addressCount}" class="form-control" placeholder="Enter street name" name="Addresses[${addressCount-1}].Street"> </div> <div class="col-md-2 mb-3" id="barangay${addressCount}"> <label class="form-label">Barangay</label> <input type="text" id="barangayVisible${addressCount}" class="form-control" placeholder="Enter barangay name" name="Addresses[${addressCount-1}].Barangay"> </div> <div class="col-md-2 mb-3" id="btnRemove${addressCount}"> <label class="form-label"></label> <button type="button" class="btn btn-danger remove-address-btn" onclick="removeField(${addressCount})">-</button> </div> </div> `; // 使用insertAdjacentHTML追加新元素,不破坏现有输入内容 addressesContainer.insertAdjacentHTML('beforeend', fieldHtml); } function removeField(index) { // 直接移除整个地址行,简化删除逻辑 const addressRow = document.getElementById(`addressRow${index}`); if (addressRow) { addressRow.remove(); } } // 初始化加载第一个地址字段 addAddress(); </script> }
额外说明
- 补充的
name属性格式为Addresses[索引].属性名,需确保你的Registration模型中包含List<Address> Addresses集合属性,这样表单提交时才能正确绑定数据。 - 单个地址包裹在
.row中后,删除操作只需移除整个行,避免了原代码中逐个删除列的繁琐和潜在错误。
内容的提问来源于stack exchange,提问作者Erck
相关产品推荐
相关产品推荐

