ASP.NET MVC 5多表单实现咨询:数据留存、模态框及线框图需求
Let's tackle your two scenarios one by one—both are totally feasible in ASP.NET MVC 5, and AJAX is absolutely the right tool for the job here.
1. Preserving Parent Form Data When Submitting a Child Form (AJAX-First Approach)
First off: yes, you can absolutely use AJAX to avoid losing parent form data when handling child submissions. Here's the cleanest way to do it without full page redirects:
- Skip the full page jump: Instead of sending users to a separate page for the child form, load the child form directly in a modal window on the parent page. This keeps the parent form's data intact in the browser at all times.
- AJAX-powered child submission: When the user fills out the child form and clicks submit, use jQuery AJAX to post the data to your MVC action method. The action will handle saving to the relevant database tables and return a JSON success/error response.
- Update the parent UI (if needed): After a successful submission, you can refresh any related sections on the parent (like a list of child records) without reloading the entire page.
If your business logic requires a full page redirect to the child form, you can still preserve parent data with these workarounds:
- Temporary server-side storage: Before redirecting, save the parent form's model data to
TempData(short-lived, cleared after one request) orSession(persists longer) in your MVC action. When the user returns to the parent form, populate the fields fromTempData/Sessionand clear the storage to avoid stale data. - Client-side local storage: Use JavaScript to save the parent form's input values to
localStorageright before navigating to the child page. When the user comes back, read fromlocalStorageand repopulate the parent form fields.
Quick AJAX Example for Child Form Submission
// Triggered when child form in modal is submitted $('#childForm').on('submit', function(e) { e.preventDefault(); $.ajax({ url: '@Url.Action("SaveChild", "Parent")', type: 'POST', data: $(this).serialize(), success: function(response) { if (response.success) { $('#childModal').modal('hide'); $('#childForm')[0].reset(); // Clear form fields refreshChildRecords(); // Function to reload child list via AJAX } else { alert('Error saving child record: ' + response.message); } }, error: function() { alert('An unexpected error occurred.'); } }); });
2. Implementing In-Line Child Form Lists with Modal Add/Edit
For the scenario where you need to add multiple child records and display them directly in the parent form, here's a step-by-step implementation:
Step 1: Parent View Structure
In your parent view, add a section to display existing child records (e.g., an HTML table). Include a button to open the "Add Child" modal:
<div class="parent-form"> <!-- Parent form fields here --> <input type="text" name="ParentName" value="@Model.ParentName" class="form-control mb-2" /> <input type="date" name="ParentDate" value="@Model.ParentDate" class="form-control mb-2" /> <textarea name="ParentDescription" class="form-control mb-4">@Model.ParentDescription</textarea> <!-- Child Records List --> <div class="child-records"> <h4>Child Entries</h4> <table class="table table-striped"> <thead> <tr> <th>Child Name</th> <th>Child Value</th> <th>Actions</th> </tr> </thead> <tbody id="childRecordsTable"> @foreach (var child in Model.ChildRecords) { <tr> <td>@child.ChildName</td> <td>@child.ChildValue</td> <td> <button class="btn btn-sm btn-primary edit-child" data-id="@child.Id">Edit</button> <button class="btn btn-sm btn-danger delete-child" data-id="@child.Id">Delete</button> </td> </tr> } </tbody> </table> <button id="addChildBtn" class="btn btn-success">+ Add New Child</button> </div> </div>
Step 2: Bootstrap Modal for Child Input
Add a hidden modal (using Bootstrap, which is common in MVC 5 projects) to handle adding/editing child records:
<div class="modal fade" id="childModal" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="childModalTitle">Add Child Entry</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <form id="childForm"> <div class="modal-body"> <input type="hidden" name="ChildId" id="childId" /> <input type="hidden" name="ParentId" value="@Model.ParentId" /> <!-- Link to parent record --> <div class="form-group"> <label for="childName">Child Name</label> <input type="text" class="form-control" name="ChildName" id="childName" required /> </div> <div class="form-group"> <label for="childValue">Child Value</label> <input type="number" class="form-control" name="ChildValue" id="childValue" required /> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> <button type="submit" class="btn btn-primary">Save</button> </div> </form> </div> </div> </div>
Step 3: Dynamic Modal Behavior & AJAX
Add JavaScript to handle opening the modal (for add/edit) and submitting the form:
// Open empty modal for adding new child $('#addChildBtn').on('click', function() { $('#childModalTitle').text('Add Child Entry'); $('#childId').val(''); // Clear ID for new record $('#childForm')[0].reset(); $('#childModal').modal('show'); }); // Open modal pre-populated for editing existing child function editChildHandler() { var childId = $(this).data('id'); $.get('@Url.Action("GetChild", "Parent")/' + childId, function(child) { $('#childModalTitle').text('Edit Child Entry'); $('#childId').val(child.Id); $('#childName').val(child.ChildName); $('#childValue').val(child.ChildValue); $('#childModal').modal('show'); }); } // Bind edit event initially $('.edit-child').on('click', editChildHandler); // Submit child form via AJAX $('#childForm').on('submit', function(e) { e.preventDefault(); $.ajax({ url: '@Url.Action("SaveChild", "Parent")', type: 'POST', data: $(this).serialize(), success: function(response) { if (response.success) { $('#childModal').modal('hide'); refreshChildRecords(); // Reload child list } else { alert('Error: ' + response.message); } } }); }); // Function to refresh child records list function refreshChildRecords() { $.get('@Url.Action("GetChildRecords", "Parent")/' + '@Model.ParentId', function(records) { var tableBody = $('#childRecordsTable'); tableBody.empty(); $.each(records, function(index, child) { var row = '<tr>' + '<td>' + child.ChildName + '</td>' + '<td>' + child.ChildValue + '</td>' + '<td>' + '<button class="btn btn-sm btn-primary edit-child" data-id="' + child.Id + '">Edit</button>' + '<button class="btn btn-sm btn-danger delete-child" data-id="' + child.Id + '">Delete</button>' + '</td>' + '</tr>'; tableBody.append(row); }); // Re-bind edit/delete events for new rows $('.edit-child').off('click').on('click', editChildHandler); $('.delete-child').off('click').on('click', deleteChildHandler); }); } // Optional: Delete child record via AJAX function deleteChildHandler() { if (confirm('Are you sure you want to delete this child entry?')) { var childId = $(this).data('id'); $.post('@Url.Action("DeleteChild", "Parent")/' + childId, function(response) { if (response.success) { refreshChildRecords(); } else { alert('Error deleting record: ' + response.message); } }); } } $('.delete-child').on('click', deleteChildHandler);
Step 4: MVC Action Methods
You'll need corresponding action methods in your controller to handle saving, fetching, and deleting child records (returning JSON responses for AJAX calls). For example:
[HttpPost] public JsonResult SaveChild(ChildViewModel model) { if (ModelState.IsValid) { // Save to database (link to parent via ParentId) _childService.Save(model); return Json(new { success = true }); } return Json(new { success = false, message = "Invalid form data" }); } public JsonResult GetChild(int id) { var child = _childService.GetById(id); return Json(child, JsonRequestBehavior.AllowGet); }
Wireframe Overview
Here's a simple ASCII wireframe to visualize the flow:
+---------------------------------------- Parent Form ----------------------------------------+ | | | Parent Form Fields: | | [Name: _______________] [Date: ____________] [Description: ___________________________] | | | | +---------------------- Child Records List ----------------------+ | | | Child Name | Child Value | Actions | | | | -------------|---------------|-------------------| | | | Foo | 100 | [Edit] [Delete] | | | | Bar | 200 | [Edit] [Delete] | | | | -------------------------------------------------------------| | | | [+ Add New Child] Button | | +------------------------------------------------------------------+ | | | +----------------------------------------------------------------------------------------------+ +---------------------------------------- Add/Edit Child Modal --------------------------------+ | [X] Close | | | | [Modal Title: Add/Edit Child Entry] | | Child Name: [_______________] | | Child Value: [_______________] | | | | [Submit] [Cancel] | +----------------------------------------------------------------------------------------------+
内容的提问来源于stack exchange,提问作者Dixie Flyer

