Blazor EditForm创建子数据:返回后表单数据丢失求助
解决方案:Blazor任务表单跳转后数据丢失及内嵌客户创建的实现
一、解决跳转后任务数据丢失的问题
跳转至客户表单后,原任务组件会被销毁,返回时重新初始化,导致数据丢失。以下是两种可靠的解决方式:
1. 利用浏览器本地存储临时保存数据
通过LocalStorage在跳转前序列化存储当前任务数据,返回时反序列化恢复:
@inject Blazored.LocalStorage.ILocalStorageService LocalStorage @inject NavigationManager NavManager <EditForm Model="@CurrentTask" OnValidSubmit="@SaveTask"> <InputLabel>任务标题</InputLabel> <InputText @bind-Value="CurrentTask.Title" class="form-control" /> <InputLabel>搜索客户</InputLabel> <InputText @bind-Value="SearchKeyword" class="form-control" /> <button @onclick="@NavigateToCreateCustomer" class="btn btn-link">客户不存在?去创建</button> <button type="submit" class="btn btn-primary mt-3">保存任务</button> </EditForm> @code { private TaskModel CurrentTask { get; set; } = new(); private string SearchKeyword { get; set; } protected override async Task OnInitializedAsync() { // 返回时读取临时存储的任务数据 var savedTaskJson = await LocalStorage.GetItemAsync<string>("TempPendingTask"); if (!string.IsNullOrEmpty(savedTaskJson)) { CurrentTask = JsonSerializer.Deserialize<TaskModel>(savedTaskJson); // 读取后清理存储,避免重复加载 await LocalStorage.RemoveItemAsync("TempPendingTask"); } } private async Task NavigateToCreateCustomer() { // 跳转前序列化保存当前任务数据 var taskJson = JsonSerializer.Serialize(CurrentTask); await LocalStorage.SetItemAsync("TempPendingTask", taskJson); NavManager.NavigateTo("/customers/create"); } private async Task SaveTask() { // 调用API保存任务 await TaskService.SaveTaskAsync(CurrentTask); // 清理临时存储 await LocalStorage.RemoveItemAsync("TempPendingTask"); NavManager.NavigateTo("/tasks"); } }
客户表单保存后直接返回任务创建页即可:
private async Task SaveCustomer() { await CustomerService.SaveCustomerAsync(CurrentCustomer); NavManager.NavigateTo("/tasks/create"); }
2. 使用全局状态服务暂存数据
创建一个Scoped状态服务,在组件间共享未完成的任务数据:
// 全局状态服务 public class PendingTaskState { public TaskModel UnfinishedTask { get; set; } } // Program.cs中注册为Scoped服务 builder.Services.AddScoped<PendingTaskState>();
在任务表单中注入并使用:
@inject PendingTaskState TaskState @inject NavigationManager NavManager <EditForm Model="@CurrentTask" OnValidSubmit="@SaveTask"> <!-- 表单内容同前 --> </EditForm> @code { private TaskModel CurrentTask { get; set; } protected override void OnInitialized() { // 恢复暂存的任务数据 if (TaskState.UnfinishedTask != null) { CurrentTask = TaskState.UnfinishedTask; TaskState.UnfinishedTask = null; // 清空状态,避免重复加载 } else { CurrentTask = new TaskModel(); } } private void NavigateToCreateCustomer() { // 暂存当前任务 TaskState.UnfinishedTask = CurrentTask; NavManager.NavigateTo("/customers/create"); } private async Task SaveTask() { await TaskService.SaveTaskAsync(CurrentTask); NavManager.NavigateTo("/tasks"); } }
二、直接在任务表单内录入客户详情的实现
完全支持内嵌客户创建功能,推荐两种方式:
1. 内嵌客户创建组件
创建独立的CustomerCreateComponent,在任务表单中按需显示:
// 任务表单组件 <EditForm Model="@CurrentTask" OnValidSubmit="@SaveTask"> <!-- 任务字段 --> <InputText @bind-Value="CurrentTask.Title" /> <div class="mt-3"> <InputText @bind-Value="SearchKeyword" placeholder="搜索客户" /> <button @onclick="@(() => ShowCustomerForm = !ShowCustomerForm)" class="btn btn-sm btn-secondary ms-2"> @(ShowCustomerForm ? "收起创建表单" : "客户不存在?直接创建") </button> </div> <!-- 内嵌客户创建组件 --> @if (ShowCustomerForm) { <CustomerCreateComponent OnCustomerSaved="@HandleCustomerCreated" /> } <button type="submit" class="btn btn-primary mt-3">保存任务</button> </EditForm> @code { private bool ShowCustomerForm { get; set; } private TaskModel CurrentTask { get; set; } = new(); private string SearchKeyword { get; set; } private void HandleCustomerCreated(CustomerModel newCustomer) { // 将新建客户ID关联到任务 CurrentTask.CustomerId = newCustomer.Id; ShowCustomerForm = false; } }
客户创建组件代码:
[Parameter] public EventCallback<CustomerModel> OnCustomerSaved { get; set; } private CustomerModel CurrentCustomer { get; set; } = new(); private async Task SaveCustomer() { var savedCustomer = await CustomerService.SaveCustomerAsync(CurrentCustomer); await OnCustomerSaved.InvokeAsync(savedCustomer); }
2. 使用联合模型同时编辑任务和客户
定义包含任务与客户的联合模型,在同一个表单中完成两者的录入:
<EditForm Model="@TaskWithCustomer" OnValidSubmit="@SaveTaskAndCustomer"> <h5>任务信息</h5> <InputText @bind-Value="TaskWithCustomer.Task.Title" class="form-control mb-2" /> <h5 class="mt-3">客户信息</h5> <InputText @bind-Value="TaskWithCustomer.Customer.Name" class="form-control mb-2" /> <InputText @bind-Value="TaskWithCustomer.Customer.Email" class="form-control mb-2" /> <button type="submit" class="btn btn-primary mt-3">保存任务及客户</button> </EditForm> @code { private TaskWithCustomerModel TaskWithCustomer { get; set; } = new(); private async Task SaveTaskAndCustomer() { // 先保存客户 var savedCustomer = await CustomerService.SaveCustomerAsync(TaskWithCustomer.Customer); // 关联客户ID到任务 TaskWithCustomer.Task.CustomerId = savedCustomer.Id; // 保存任务 await TaskService.SaveTaskAsync(TaskWithCustomer.Task); NavManager.NavigateTo("/tasks"); } // 联合模型定义 public class TaskWithCustomerModel { public TaskModel Task { get; set; } = new(); public CustomerModel Customer { get; set; } = new(); } }
内容的提问来源于stack exchange,提问作者Tala
相关产品推荐
相关产品推荐

