You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor Bootstrap v3.3.1详情视图展开触发事件的实现方法

在Blazor Bootstrap v3.3.1中实现展开详情视图时触发API调用

Blazor Bootstrap v3.3.1的Grid组件目前没有内置的"详情展开"事件,但可以通过以下两种简便方式实现需求:

方法一:监听Grid的ExpandedItems集合变化

Grid组件会自动维护ExpandedItems集合,记录当前展开的行数据。我们可以绑定这个集合,在组件渲染后检查新增的展开项,触发API调用:

修改后的代码示例

<Grid TItem="Employee1"
      Class="table table-hover border-top"
      Data="employees"
      AllowDetailView="true"
      @bind-ExpandedItems="expandedEmployees"> <!-- 绑定展开项集合 -->

    <!-- 原有列定义保持不变 -->
    <GridColumns>
        <GridColumn TItem="Employee1" HeaderText="Id" PropertyName="Id">
            @context.Id
        </GridColumn>
        <GridColumn TItem="Employee1" HeaderText="Employee Name" PropertyName="Name">
            @context.Name
        </GridColumn>
        <GridColumn TItem="Employee1" HeaderText="Designation" PropertyName="Designation">
            @context.Designation
        </GridColumn>
        <GridColumn TItem="Employee1" HeaderText="DOJ" PropertyName="DOJ">
            @context.DOJ
        </GridColumn>
        <GridColumn TItem="Employee1" HeaderText="Active" PropertyName="IsActive">
            @context.IsActive
        </GridColumn>
    </GridColumns>

    <!-- 原有详情视图内容保持不变 -->
    <GridDetailView TItem="Employee1">
        <Grid TItem="Employee1"
              Class="table table-hover border-top"
              Data="employees"
              AllowDetailView="true">

            <GridColumns>
                <GridColumn TItem="Employee1" Context="emp1" HeaderText="Id" PropertyName="Id">
                    @emp1.Id
                </GridColumn>
                <GridColumn TItem="Employee1" Context="emp1" HeaderText="Employee Name" PropertyName="Name">
                    @emp1.Name
                </GridColumn>
                <GridColumn TItem="Employee1" Context="emp1" HeaderText="Designation" PropertyName="Designation">
                    @emp1.Designation
                </GridColumn>
                <GridColumn TItem="Employee1" Context="emp1" HeaderText="DOJ" PropertyName="DOJ">
                    @emp1.DOJ
                </GridColumn>
                <GridColumn TItem="Employee1" Context="emp1" HeaderText="Active" PropertyName="IsActive">
                    @emp1.IsActive
                </GridColumn>
            </GridColumns>

            <GridDetailView TItem="Employee1" Context="emp1">
                <div class="row">
                    <div class="col-2 fw-bold">Id</div>
                    <div class="col">@emp1.Id</div>
                </div>
                <div class="row">
                    <div class="col-2 fw-bold">Name</div>
                    <div class="col">@emp1.Name</div>
                </div>
                <div class="row">
                    <div class="col-2 fw-bold">Designation</div>
                    <div class="col">@emp1.Designation</div>
                </div>
                <div class="row">
                    <div class="col-2 fw-bold">DOJ</div>
                    <div class="col">@emp1.DOJ</div>
                </div>
                <div class="row">
                    <div class="col-2 fw-bold">IsActive</div>
                    <div class="col">@emp1.IsActive</div>
                </div>
            </GridDetailView>

        </Grid>
    </GridDetailView>
</Grid>

@code {
    private List<Employee1> employees = new List<Employee1> {
        new Employee1 { Id = 107, Name = "Alice", Designation = "AI Engineer", DOJ = new DateOnly(1998, 11, 17), IsActive = true },
        new Employee1 { Id = 103, Name = "Bob", Designation = "Senior DevOps Engineer", DOJ = new DateOnly(1985, 1, 5), IsActive = true },
        new Employee1 { Id = 106, Name = "John", Designation = "Data Engineer", DOJ = new DateOnly(1995, 4, 17), IsActive = true },
        new Employee1 { Id = 104, Name = "Pop", Designation = "Associate Architect", DOJ = new DateOnly(1985, 6, 8), IsActive = false },
        new Employee1 { Id = 105, Name = "Ronald", Designation = "Senior Data Engineer", DOJ = new DateOnly(1991, 8, 23), IsActive = true }
    };
    private List<Employee1> expandedEmployees = new();
    private HashSet<int> processedExpandedIds = new(); // 避免重复触发API调用

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (!firstRender)
        {
            // 筛选出新增的展开项
            var newlyExpanded = expandedEmployees.Where(e => !processedExpandedIds.Contains(e.Id)).ToList();
            foreach (var item in newlyExpanded)
            {
                // 执行API调用或其他业务操作
                await LoadEmployeeDetails(item.Id);
                processedExpandedIds.Add(item.Id);
            }

            // 可选:处理收起的项,清理已记录的ID
            var removedIds = processedExpandedIds.Where(id => !expandedEmployees.Any(e => e.Id == id)).ToList();
            foreach (var id in removedIds)
            {
                processedExpandedIds.Remove(id);
            }
        }
        await base.OnAfterRenderAsync(firstRender);
    }

    private async Task LoadEmployeeDetails(int employeeId)
    {
        // 替换为实际API调用逻辑
        // var details = await _employeeApi.GetEmployeeDetailsAsync(employeeId);
        Console.WriteLine($"加载员工ID {employeeId} 的详情数据");
    }

    public record class Employee1
    {
        public int Id { get; set; }
        public string? Name { get; set; }
        public string? Designation { get; set; }
        public DateOnly DOJ { get; set; }
        public bool IsActive { get; set; }
    }
}

方法二:自定义展开按钮,手动控制展开逻辑

替换Grid默认的展开图标,使用自定义按钮,点击时先执行API调用,再触发详情展开:

修改后的代码示例

<Grid TItem="Employee1"
      Class="table table-hover border-top"
      Data="employees"
      AllowDetailView="false"> <!-- 关闭默认展开逻辑 -->

    <GridColumns>
        <!-- 自定义展开按钮列 -->
        <GridColumn TItem="Employee1" Width="50">
            <button type="button" class="btn btn-link p-0" @onclick="() => ToggleDetail(context)">
                @(expandedEmployeeIds.Contains(context.Id) ? "▼" : "▶")
            </button>
        </GridColumn>
        <!-- 原有列定义保持不变 -->
        <GridColumn TItem="Employee1" HeaderText="Id" PropertyName="Id">
            @context.Id
        </GridColumn>
        <GridColumn TItem="Employee1" HeaderText="Employee Name" PropertyName="Name">
            @context.Name
        </GridColumn>
        <GridColumn TItem="Employee1" HeaderText="Designation" PropertyName="Designation">
            @context.Designation
        </GridColumn>
        <GridColumn TItem="Employee1" HeaderText="DOJ" PropertyName="DOJ">
            @context.DOJ
        </GridColumn>
        <GridColumn TItem="Employee1" HeaderText="Active" PropertyName="IsActive">
            @context.IsActive
        </GridColumn>
    </GridColumns>

    <!-- 手动渲染详情视图 -->
    @foreach (var emp in employees)
    {
        if (expandedEmployeeIds.Contains(emp.Id))
        {
            <tr>
                <td colspan="6"> <!-- 列数需与Grid总列数一致 -->
                    <div class="p-3">
                        <Grid TItem="Employee1"
                              Class="table table-hover border-top"
                              Data="employees"
                              AllowDetailView="true">

                            <GridColumns>
                                <GridColumn TItem="Employee1" Context="emp1" HeaderText="Id" PropertyName="Id">
                                    @emp1.Id
                                </GridColumn>
                                <GridColumn TItem="Employee1" Context="emp1" HeaderText="Employee Name" PropertyName="Name">
                                    @emp1.Name
                                </GridColumn>
                                <GridColumn TItem="Employee1" Context="emp1" HeaderText="Designation" PropertyName="Designation">
                                    @emp1.Designation
                                </GridColumn>
                                <GridColumn TItem="Employee1" Context="emp1" HeaderText="DOJ" PropertyName="DOJ">
                                    @emp1.DOJ
                                </GridColumn>
                                <GridColumn TItem="Employee1" Context="emp1" HeaderText="Active" PropertyName="IsActive">
                                    @emp1.IsActive
                                </GridColumn>
                            </GridColumns>

                            <GridDetailView TItem="Employee1" Context="emp1">
                                <div class="row">
                                    <div class="col-2 fw-bold">Id</div>
                                    <div class="col">@emp1.Id</div>
                                </div>
                                <div class="row">
                                    <div class="col-2 fw-bold">Name</div>
                                    <div class="col">@emp1.Name</div>
                                </div>
                                <div class="row">
                                    <div class="col-2 fw-bold">Designation</div>
                                    <div class="col">@emp1.Designation</div>
                                </div>
                                <div class="row">
                                    <div class="col-2 fw-bold">DOJ</div>
                                    <div class="col">@emp1.DOJ</div>
                                </div>
                                <div class="row">
                                    <div class="col-2 fw-bold">IsActive</div>
                                    <div class="col">@emp1.IsActive</div>
                                </div>
                            </GridDetailView>

                        </Grid>
                    </div>
                </td>
            </tr>
        }
    }
</Grid>

@code {
    private List<Employee1> employees = new List<Employee1> {
        new Employee1 { Id = 107, Name = "Alice", Designation = "AI Engineer", DOJ = new DateOnly(1998, 11, 17), IsActive = true },
        new Employee1 { Id = 103, Name = "Bob", Designation = "Senior DevOps Engineer", DOJ = new DateOnly(1985, 1, 5), IsActive = true },
        new Employee1 { Id = 106, Name = "John", Designation = "Data Engineer", DOJ = new DateOnly(1995, 4, 17), IsActive = true },
        new Employee1 { Id = 104, Name = "Pop", Designation = "Associate Architect", DOJ = new DateOnly(1985, 6, 8), IsActive = false },
        new Employee1 { Id = 105, Name = "Ronald", Designation = "Senior Data Engineer", DOJ = new DateOnly(1991, 8, 23), IsActive = true }
    };
    private HashSet<int> expandedEmployeeIds = new();

    private async Task ToggleDetail(Employee1 employee)
    {
        if (expandedEmployeeIds.Contains(employee.Id))
        {
            expandedEmployeeIds.Remove(employee.Id);
        }
        else
        {
            // 先执行API调用加载数据
            await LoadEmployeeDetails(employee.Id);
            expandedEmployeeIds.Add(employee.Id);
        }
        StateHasChanged();
    }

    private async Task LoadEmployeeDetails(int employeeId)
    {
        // 替换为实际API调用逻辑
        Console.WriteLine($"加载员工ID {employeeId} 的详情数据");
    }

    public record class Employee1
    {
        public int Id { get; set; }
        public string? Name { get; set; }
        public string? Designation { get; set; }
        public DateOnly DOJ { get; set; }
        public bool IsActive { get; set; }
    }
}

说明

  • 方法一利用组件内置的ExpandedItems集合,无需修改原有布局,适合需要保留默认展开样式的场景。
  • 方法二完全自定义展开逻辑,灵活性更高,适合需要自定义按钮样式或添加额外交互的场景。

内容的提问来源于stack exchange,提问作者tuomis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 06:32:04