Skip to content

Commit 413451b

Browse files
authored
fix(Table): dynamically added columns are not visible in the UI (#8241)
* feat: 增加列宽重置逻辑 * test: 增加单元测试 * chore: bump version 10.8.2-beta01
1 parent be16982 commit 413451b

3 files changed

Lines changed: 158 additions & 1 deletion

File tree

‎src/BootstrapBlazor/BootstrapBlazor.csproj‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk.Razor">
22

33
<PropertyGroup>
4-
<Version>10.8.1</Version>
4+
<Version>10.8.2-beta01</Version>
55
</PropertyGroup>
66

77
<ItemGroup>

‎src/BootstrapBlazor/Components/Table/Table.razor.cs‎

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,6 +1463,7 @@ private void ResetTableColumns()
14631463
// 未匹配到状态的列按其在 Columns 中的相对位置插入而不是追加到末尾
14641464
// 防止多语言切换等场景列字段名变化导致仅部分列匹配时列顺序错乱
14651465
var insertIndex = 0;
1466+
var widthChanged = false;
14661467
foreach (var col in Columns)
14671468
{
14681469
if (col.GetIgnore())
@@ -1474,16 +1475,23 @@ private void ResetTableColumns()
14741475
if (stateMap.TryGetValue(name, out var item))
14751476
{
14761477
item.DisplayName = col.GetDisplayName();
1478+
widthChanged = NormalizeVisibleColumnWidth(item, col) || widthChanged;
14771479
insertIndex = _tableColumnStates.IndexOf(item) + 1;
14781480
}
14791481
else
14801482
{
14811483
item = CreateTableColumnState(col);
1484+
widthChanged = NormalizeVisibleColumnWidth(item, col) || widthChanged;
14821485
_tableColumnStates.Insert(insertIndex, item);
14831486
insertIndex++;
14841487
}
14851488
}
14861489

1490+
if (widthChanged)
1491+
{
1492+
UpdateTableColumnStateWidth();
1493+
}
1494+
14871495
// 根据 _tableColumnStates 顺序重建可见列顺序
14881496
for (var index = 0; index < _tableColumnStates.Count; index++)
14891497
{
@@ -1506,6 +1514,45 @@ private void ResetTableColumns()
15061514
Visible = col.GetVisible(_screenSize)
15071515
};
15081516

1517+
private bool NormalizeVisibleColumnWidth(TableColumnState item, ITableColumn col)
1518+
{
1519+
if (!item.Visible || item.Width.HasValue)
1520+
{
1521+
return false;
1522+
}
1523+
1524+
item.Width = GetDefaultColumnStateWidth(col);
1525+
return true;
1526+
}
1527+
1528+
private int GetDefaultColumnStateWidth(ITableColumn col) => col.Width ?? (col.Fixed ? DefaultFixedColumnWidth : ColumnMinWidth ?? Options.CurrentValue.TableSettings.ColumnMinWidth);
1529+
1530+
private void UpdateTableColumnStateWidth()
1531+
{
1532+
var tableWidth = 0;
1533+
var useTableWidth = true;
1534+
foreach (var column in _tableColumnStateCache.Columns)
1535+
{
1536+
if (!column.Visible)
1537+
{
1538+
continue;
1539+
}
1540+
1541+
if (column.Width.HasValue)
1542+
{
1543+
tableWidth += column.Width.Value;
1544+
}
1545+
else
1546+
{
1547+
useTableWidth = false;
1548+
break;
1549+
}
1550+
}
1551+
1552+
_tableColumnStateCache.TableWidth = useTableWidth ? tableWidth : 0;
1553+
UpdateTableWidth();
1554+
}
1555+
15091556
private async Task OnTableRenderAsync(bool firstRender)
15101557
{
15111558
if (firstRender)

‎test/UnitTest/Components/TableTest.cs‎

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,116 @@ public async Task ShowColumnList_Ok()
998998
Assert.Equal("地址", labels[1].TextContent);
999999
}
10001000

1001+
[Fact]
1002+
public void ShowColumnList_NewVisibleColumnUseDefaultWidth_Ok()
1003+
{
1004+
var state = new TableColumnClientStatus()
1005+
{
1006+
TableWidth = 240,
1007+
Columns =
1008+
[
1009+
new TableColumnState() { Name = nameof(Foo.Name), Visible = true, Width = 120 },
1010+
new TableColumnState() { Name = nameof(Foo.Address), Visible = true, Width = 120 },
1011+
new TableColumnState() { Name = nameof(Foo.Count), Visible = true },
1012+
new TableColumnState() { Name = nameof(Foo.DateTime), Visible = true }
1013+
]
1014+
};
1015+
1016+
Context.JSInterop.Setup<TableColumnClientStatus>("getColumnStates", "test-new-column").SetResult(state);
1017+
var localizer = Context.Services.GetRequiredService<IStringLocalizer<Foo>>();
1018+
var cut = Context.Render<BootstrapBlazorRoot>(pb =>
1019+
{
1020+
pb.AddChildContent<Table<Foo>>(pb =>
1021+
{
1022+
pb.Add(a => a.RenderMode, TableRenderMode.Table);
1023+
pb.Add(a => a.AllowResizing, true);
1024+
pb.Add(a => a.ColumnMinWidth, 80);
1025+
pb.Add(a => a.Items, Foo.GenerateFoo(localizer, 2));
1026+
pb.Add(a => a.TableColumns, foo => builder =>
1027+
{
1028+
builder.OpenComponent<TableColumn<Foo, string>>(0);
1029+
builder.AddAttribute(1, "Field", "Name");
1030+
builder.AddAttribute(2, "FieldExpression", Utility.GenerateValueExpression(foo, "Name", typeof(string)));
1031+
builder.CloseComponent();
1032+
1033+
builder.OpenComponent<TableColumn<Foo, string>>(3);
1034+
builder.AddAttribute(4, "Field", "Address");
1035+
builder.AddAttribute(5, "FieldExpression", Utility.GenerateValueExpression(foo, "Address", typeof(string)));
1036+
builder.CloseComponent();
1037+
1038+
builder.OpenComponent<TableColumn<Foo, int>>(6);
1039+
builder.AddAttribute(7, "Field", foo.Count);
1040+
builder.AddAttribute(8, "FieldExpression", Utility.GenerateValueExpression(foo, "Count", typeof(int)));
1041+
builder.AddAttribute(9, nameof(ITableColumn.Width), 90);
1042+
builder.CloseComponent();
1043+
1044+
builder.OpenComponent<TableColumn<Foo, bool>>(10);
1045+
builder.AddAttribute(11, "Field", foo.Complete);
1046+
builder.AddAttribute(12, "FieldExpression", Utility.GenerateValueExpression(foo, "Complete", typeof(bool)));
1047+
builder.CloseComponent();
1048+
1049+
builder.OpenComponent<TableColumn<Foo, DateTime?>>(13);
1050+
builder.AddAttribute(14, "Field", foo.DateTime);
1051+
builder.AddAttribute(15, "FieldExpression", Utility.GenerateValueExpression(foo, "DateTime", typeof(DateTime?)));
1052+
builder.AddAttribute(16, nameof(ITableColumn.Fixed), true);
1053+
builder.CloseComponent();
1054+
});
1055+
pb.Add(a => a.ClientTableName, "test-new-column");
1056+
});
1057+
});
1058+
1059+
cut.Contains("style=\"width: 90px;\"");
1060+
cut.Contains("style=\"width: 80px;\"");
1061+
cut.Contains("style=\"width: 200px;\"");
1062+
}
1063+
1064+
[Fact]
1065+
public void ShowColumnList_NewVisibleColumnUseOptionDefaultWidth_Ok()
1066+
{
1067+
var state = new TableColumnClientStatus()
1068+
{
1069+
TableWidth = 240,
1070+
Columns =
1071+
[
1072+
new TableColumnState() { Name = nameof(Foo.Name), Visible = true, Width = 120 },
1073+
new TableColumnState() { Name = nameof(Foo.Address), Visible = true, Width = 120 }
1074+
]
1075+
};
1076+
1077+
Context.JSInterop.Setup<TableColumnClientStatus>("getColumnStates", "test-new-column-option-width").SetResult(state);
1078+
var localizer = Context.Services.GetRequiredService<IStringLocalizer<Foo>>();
1079+
var cut = Context.Render<BootstrapBlazorRoot>(pb =>
1080+
{
1081+
pb.AddChildContent<Table<Foo>>(pb =>
1082+
{
1083+
pb.Add(a => a.RenderMode, TableRenderMode.Table);
1084+
pb.Add(a => a.AllowResizing, true);
1085+
pb.Add(a => a.Items, Foo.GenerateFoo(localizer, 2));
1086+
pb.Add(a => a.TableColumns, foo => builder =>
1087+
{
1088+
builder.OpenComponent<TableColumn<Foo, string>>(0);
1089+
builder.AddAttribute(1, "Field", "Name");
1090+
builder.AddAttribute(2, "FieldExpression", Utility.GenerateValueExpression(foo, "Name", typeof(string)));
1091+
builder.CloseComponent();
1092+
1093+
builder.OpenComponent<TableColumn<Foo, string>>(3);
1094+
builder.AddAttribute(4, "Field", "Address");
1095+
builder.AddAttribute(5, "FieldExpression", Utility.GenerateValueExpression(foo, "Address", typeof(string)));
1096+
builder.CloseComponent();
1097+
1098+
builder.OpenComponent<TableColumn<Foo, int>>(6);
1099+
builder.AddAttribute(7, "Field", foo.Count);
1100+
builder.AddAttribute(8, "FieldExpression", Utility.GenerateValueExpression(foo, "Count", typeof(int)));
1101+
builder.CloseComponent();
1102+
});
1103+
pb.Add(a => a.ClientTableName, "test-new-column-option-width");
1104+
});
1105+
});
1106+
1107+
cut.Contains("style=\"width: 64px;\"");
1108+
cut.Contains("style=\"width: 304px;\"");
1109+
}
1110+
10011111
[Fact]
10021112
public void ShowCardView_Ok()
10031113
{

0 commit comments

Comments
 (0)