Table组件新增动态设置固定列的功能,同时固定列支持持久化#8110
Conversation
refactor: 可以动态设置固定列,同时固定列支持表格持久化
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8110 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 766 766
Lines 34204 34224 +20
Branches 4696 4701 +5
=========================================
+ Hits 34204 34224 +20
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Thanks for your PR, @Tony-ST0754. Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
Reviewer's GuideAdds persistence and dynamic updating of fixed columns in the Table component by extending the column state model, wiring fixed state through C# and JS, and introducing a new instance method and JS helper to sync client-side fixed-column changes into persistent storage. Sequence diagram for updating and persisting fixed table columnssequenceDiagram
actor User
participant Table as Table
participant JSRuntime as JSRuntime
participant TableJs as TableJs
participant LocalStorage as LocalStorage
User->>Table: UpdateTableColumnClientStatus()
loop for each item in Columns
Table->>Table: _tableColumnStates.Find(...).Fixed = item.Fixed
end
Table->>Table: StateHasChanged()
Table->>JSRuntime: InvokeVoidAsync(updateColumnStates, Id)
JSRuntime->>TableJs: updateColumnStates(id)
TableJs->>TableJs: getColumnStateObject(table)
TableJs->>LocalStorage: saveColumnStateToLocalstorage(table, state)
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- In
UpdateTableColumnClientStatus, usingFind(... )!assumes every column has a corresponding_tableColumnStatesentry; consider handling the case where no match is found to avoid a potentialNullReferenceExceptionwhen columns are dynamically added or renamed. - In
updateColumnStates(Table.razor.js),Data.get(id)is used without checking for an undefined result; adding a guard (and early return/log) would prevent runtime errors if the table instance has not been registered or has been cleaned up when this function is called.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `UpdateTableColumnClientStatus`, using `Find(... )!` assumes every column has a corresponding `_tableColumnStates` entry; consider handling the case where no match is found to avoid a potential `NullReferenceException` when columns are dynamically added or renamed.
- In `updateColumnStates` (Table.razor.js), `Data.get(id)` is used without checking for an undefined result; adding a guard (and early return/log) would prevent runtime errors if the table instance has not been registered or has been cleaned up when this function is called.
## Individual Comments
### Comment 1
<location path="src/BootstrapBlazor/Components/Table/Table.razor.cs" line_range="1955-1957" />
<code_context>
+ if (Columns.Count != 0)
+ {
+ // 用户在外面变更了列状态后,为避免用户变更状态丢失,须将变更后的状态同步到缓存中
+ foreach (var item in Columns)
+ {
+ _tableColumnStates.Find(x => x.Name == item.GetFieldName())!.Fixed = item.Fixed;
+ }
+ StateHasChanged();
</code_context>
<issue_to_address>
**issue (bug_risk):** Avoid assuming `_tableColumnStates` always contains a matching entry for each column.
Using `!` on the `Find` result will cause a runtime exception if `Columns` and `_tableColumnStates` ever diverge (e.g., column added/removed/renamed without a matching state). Consider handling `null` and skipping or logging missing entries to keep this resilient to mismatched state.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
refactor:清除空行,增加缓存列可能为判断
There was a problem hiding this comment.
Pull request overview
This PR adds support for dynamically updating a Table’s fixed-column configuration at runtime and persisting/restoring that fixed state alongside existing client column state (width/visibility), addressing issue #8094.
Changes:
- Add
FixedtoTableColumnStateso fixed-column state can be persisted. - Extend the Table JS column-state serialization to include
fixed, and add a JS API to update stored column states. - Add
Table.UpdateTableColumnClientStatus()plus a unit test for the new behavior.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| test/UnitTest/Components/TableTest.cs | Adds a unit test covering UpdateTableColumnClientStatus and fixed-column persistence behavior. |
| src/BootstrapBlazor/Components/Table/TableColumnState.cs | Introduces Fixed property to enable persistence of fixed-column state. |
| src/BootstrapBlazor/Components/Table/Table.razor.js | Persists fixed in column state and adds updateColumnStates export. |
| src/BootstrapBlazor/Components/Table/Table.razor.cs | Restores fixed status from cached state and adds UpdateTableColumnClientStatus() instance method. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export function updateColumnStates(id) { | ||
| const el = document.getElementById(id) | ||
| if (el === null) { | ||
| return | ||
| } | ||
| let table = Data.get(id) | ||
| table.el = el; | ||
| Data.set(id, table) | ||
| const state = getColumnStateObject(table); | ||
| saveColumnStateToLocalstorage(table, state); | ||
| } |
| pb.AddChildContent<Table<Foo>>(pb => | ||
| { | ||
| pb.Add(a => a.ClientTableName, "test_update"); | ||
| pb.Add(a => a.RenderMode, TableRenderMode.Table); | ||
| pb.Add(a => a.AllowResizing, true); | ||
| pb.Add(a => a.OnQueryAsync, OnQueryAsync(localizer)); |
| var item = _tableColumnStates[index]; | ||
| var col = columnMap[item.Name]; | ||
| col.Fixed = !string.IsNullOrEmpty(item.Name) && stateMap.TryGetValue(item.Name, out var state) ? stateMap[item.Name].Fixed : false; | ||
| if (item.Visible) |
| public async Task<TableColumnClientStatus> UpdateTableColumnClientStatus() | ||
| { | ||
| if (Columns.Count != 0) | ||
| { | ||
| // 用户在外面变更了列状态后,为避免用户变更状态丢失,须将变更后的状态同步到缓存中 | ||
| foreach (var item in Columns) | ||
| { | ||
| var columnState = _tableColumnStates.Find(x => x.Name == item.GetFieldName()); | ||
| if (columnState != null) | ||
| { | ||
| columnState.Fixed = item.Fixed; | ||
| columnState.Width = item.Fixed && !item.Width.HasValue ? DefaultFixedColumnWidth : item.Width; | ||
| } | ||
| } | ||
| StateHasChanged(); | ||
| } | ||
| // 如果启用了 ClientTableName 则更新浏览器持久化列状态 | ||
| await InvokeVoidAsync("updateColumnStates", Id); | ||
|
|
||
| return _tableColumnStateCache; | ||
| } |
refactor: 可以动态设置固定列,同时固定列支持表格持久化
Link issues
fixes #8094
功能描述 / Problem Description
TableColumnState增加Fixed属性,用以持久化用UpdateTableColumnClientStatus,用以在用户自定义前n列固定时,回调生效,并同步持久化代码示例
BootstrapBlazorApp11.zip
Regression?
Risk
Verification
Packaging changes reviewed?
☑️ Self Check before Merge
Summary by Sourcery
Enable dynamic configuration and persistence of fixed table columns and expose an API to update client-side column state.
New Features:
Enhancements:
Tests: