使用Syncfusion控件的Blazor Grid如何传递主键到对话框编辑记录
问题1:获取编辑选中记录的主键
Syncfusion SfGrid提供了GetSelectedRecordsAsync()方法可以直接获取当前选中的行数据,你只需在编辑按钮的点击逻辑中调用该方法即可拿到主键,同时要注意你原有代码中if判断没有加花括号的语法问题,会导致逻辑错误。
修改My_Templates.razor的OnClicked方法:
public async Task OnClicked(Syncfusion.Blazor.Navigations.ClickEventArgs Args) { if (Args.Item.Id == "Add") { // 新增场景传递空的新对象 dialog.Title = "这是新增标题"; dialog.Text = "这是新增内容"; // 给子组件传新的空Order对象 dialog.CurrentOrder = new Order(); dialog.OpenDialog(); } if (Args.Item.Id == "Edit") { // 获取选中行 var selectedRecords = await Grid.GetSelectedRecordsAsync(); if (selectedRecords == null || !selectedRecords.Any()) { // 这里可以加未选中行的提示逻辑 return; } var editOrder = selectedRecords.First(); dialog.Title = "这是编辑标题"; dialog.Text = "这是编辑内容"; // 直接传递选中的完整记录对象,不用只传主键 dialog.CurrentOrder = editOrder; dialog.OpenDialog(); } }
问题2:子组件获取记录的方式
直接传递完整记录对象的效率更高,无需子组件再根据主键二次查询,同时你需要调整子组件的参数和数据绑定逻辑,修正原有代码的错误:
- 首先删除
ReusableDialog.razor中冗余的Employee类依赖,统一使用父组件定义的Order类(也可以把Order抽成公共类放在单独的文件里,两边都引用) - 子组件新增
EventCallback参数用于把编辑后的结果回传给父组件,删除子组件中new父组件实例的错误代码,Blazor父子组件通信不要直接new实例,要用参数和回调。
修改后的ReusableDialog.razor代码示例:
@using Syncfusion.Blazor.Popups @* 引用你Order类所在的命名空间 *@ <div id="DialogTarget"> <SfDialog Target="#DialogTarget" Width="1200px" IsModal="true" ShowCloseIcon="true" @bind-Visible="@IsOpen"> <DialogTemplates> <Header><h4 class="modal-title">@Title</h4></Header> <Content> <EditForm Model="@CurrentOrder" OnValidSubmit="@HandleValidSubmit"> <DataAnnotationsValidator /> <label>Owner</label> <InputText id="owner" @bind-Value="CurrentOrder.owner" class="form-control" /> <label>Users</label> <InputText id="users" @bind-Value="CurrentOrder.users" class="form-control" /> <label>Description</label> <InputTextArea @bind-Value="CurrentOrder.description" class="form-control" rows="4" /> <label>Fund Type</label> <p></p> <InputRadioGroup @bind-Value="CurrentOrder.fundType" class="form-control"> @foreach (var option in rdOptions) { <InputRadio Value="option" /> @option <br /> } </InputRadioGroup> </EditForm> </Content> </DialogTemplates> <DialogButtons> <DialogButton Content="OK" IsPrimary="true" OnClick="@OkClick" /> <DialogButton Content="Cancel" IsPrimary="false" OnClick="@CancelClick" /> </DialogButtons> </SfDialog> </div> @code { [Parameter] public string Title { get; set; } [Parameter] public string Text { get; set; } // 替换原来的Employee参数,统一用Order [Parameter] public Order CurrentOrder { get; set; } = new Order(); [Parameter] public string ButtonText { get; set; } = "Save"; // 回调父组件的事件,返回编辑结果和操作类型 [Parameter] public EventCallback<(bool IsConfirmed, Order ResultOrder)> OnClose { get; set; } [Parameter] public bool IsOpen { get; set; } = false; List<string> rdOptions = new List<string> { " Fund Type 1", " Fund Type 2", " Fund Type 3" }; public void OpenDialog() { IsOpen = true; StateHasChanged(); } private Task HandleValidSubmit() { // 校验通过直接触发确认回调 return OkClick(); } private async Task OkClick() { IsOpen = false; StateHasChanged(); await OnClose.InvokeAsync((true, CurrentOrder)); } private async Task CancelClick() { IsOpen = false; StateHasChanged(); await OnClose.InvokeAsync((false, null)); } }
父组件接收回调更新数据
父组件中给ReusableDialog绑定OnClose回调,处理新增/编辑后的数据源更新逻辑:
<ReusableDialog @ref="dialog" OnClose="@HandleDialogClose"></ReusableDialog>
对应的后台逻辑:
private async Task HandleDialogClose((bool IsConfirmed, Order ResultOrder) result) { if (!result.IsConfirmed || result.ResultOrder == null) { return; } if (result.ResultOrder.templateID == 0) { // 新增场景:给新记录生成主键,添加到数据源 result.ResultOrder.templateID = Orders.Max(o => o.templateID) + 1; Orders.Add(result.ResultOrder); } else { // 编辑场景:找到原有记录替换 var existOrder = Orders.FirstOrDefault(o => o.templateID == result.ResultOrder.templateID); if (existOrder != null) { existOrder.owner = result.ResultOrder.owner; existOrder.users = result.ResultOrder.users; existOrder.description = result.ResultOrder.description; existOrder.fundType = result.ResultOrder.fundType; } } // 刷新Grid await Grid.Refresh(); }
通用设计模式建议
- 模型统一:同一份业务数据不要定义多个类,抽成公共的模型类放在单独的项目文件中统一引用
- 父子组件通信遵循Blazor规范:父传子用
[Parameter],子传父用EventCallback,不要在子组件中创建父组件的实例 - 复用组件只做通用逻辑:对话框组件只负责数据收集和校验,不要耦合具体的业务保存逻辑,所有业务逻辑都放在父组件处理,提高组件复用性
内容的提问来源于stack exchange,提问作者Bryan Schmiedeler
相关产品推荐
相关产品推荐

