Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
8d7b3ef
feat(table):新增KeepAdding参数,用来处理连续新增
Tony-ST0754 Oct 9, 2026
831ddc7
chore: 增加 workbuddy 忽略配置
ArgoZhang Oct 10, 2026
6e88bb9
doc: 增加保存并新增多语言文本
ArgoZhang Oct 10, 2026
a798d7b
feat(ITableEditDialogOptions): 更新编辑弹窗配置接口增加 KeepAdding 相关属性
ArgoZhang Oct 10, 2026
dc98b58
feat: 增加保存并新增按钮默认图标
ArgoZhang Oct 10, 2026
c094263
feat: 实现 KeepAdding 按钮逻辑(不包含抽屉部分)
ArgoZhang Oct 10, 2026
0838690
doc: 增加 KeepAdding 示例
ArgoZhang Oct 10, 2026
e0e7b97
doc: 更新注释
ArgoZhang Oct 10, 2026
0697867
feat: 增加抽屉支持 KeepAdding 逻辑
ArgoZhang Oct 10, 2026
2e059de
doc: 增加抽屉形式 KeepAdding 示例
ArgoZhang Oct 10, 2026
663c9e5
chore:去掉多余代码
Tony-ST0754 Oct 10, 2026
3510cc5
Revert "feat(table):新增KeepAdding参数,用来处理连续新增"
ArgoZhang Oct 10, 2026
7e302cc
Merge branch 'feat-clone-model' into feat-table-KeepAdding
ArgoZhang Oct 10, 2026
301093d
Merge branch 'main' into feat-table-KeepAdding
ArgoZhang Oct 10, 2026
53ddfaf
refactor: 删除注释
ArgoZhang Oct 10, 2026
995da5d
refactor: EditDialog 增加类约束减少判断代码
ArgoZhang Oct 10, 2026
aefcb71
test: 更新单元测试消除警告信息
ArgoZhang Oct 10, 2026
1322f3a
test: 补充单元测试
ArgoZhang Oct 10, 2026
e06b83c
Merge branch 'main' into feat-table-KeepAdding
ArgoZhang Oct 10, 2026
252e676
chore: bump version 11.0.1-beta03
ArgoZhang Oct 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,43 @@
</Table>
</DemoBlock>

<DemoBlock Title="@Localizer["TablesKeepAddingTitle"]" Introduction="@Localizer["TablesKeepAddingIntro"]" Name="KeepAdding">
<section ignore>
<p>@((MarkupString)Localizer["TablesKeepAddingDescription"].Value)</p>
<p>@((MarkupString)Localizer["TablesKeepAddingTips"].Value)</p>
</section>
<Table TItem="Foo" @bind-Items="KeepAddingItems" ShowKeepAddingButton="true"
IsStriped="true" IsBordered="true" IsMultipleSelect="true"
ShowToolbar="true" ShowExtendButtons="true" ShowSkeleton="true"
OnAddAsync="OnKeepAddAsync"
OnKeepAddingAsync="@OnKeepAddingAsync">
<TableColumns>
<TableColumn @bind-Field="@context.DateTime" Width="180" />
<TableColumn @bind-Field="@context.Name" />
<TableColumn @bind-Field="@context.Address" />
<TableColumn @bind-Field="@context.Count" />
<TableColumn @bind-Field="@context.Complete" />
</TableColumns>
</Table>

<section ignore>
<p>@((MarkupString)Localizer["TablesKeepAddingDrawerDescription"].Value)</p>
</section>
<Table TItem="Foo" @bind-Items="KeepAddingDrawerItems" ShowKeepAddingButton="true" EditMode="EditMode.Drawer"
IsStriped="true" IsBordered="true" IsMultipleSelect="true"
ShowToolbar="true" ShowExtendButtons="true" ShowSkeleton="true"
OnAddAsync="OnKeepAddAsync"
OnKeepAddingAsync="@OnKeepAddingAsync">
<TableColumns>
<TableColumn @bind-Field="@context.DateTime" Width="180" />
<TableColumn @bind-Field="@context.Name" />
<TableColumn @bind-Field="@context.Address" />
<TableColumn @bind-Field="@context.Count" />
<TableColumn @bind-Field="@context.Complete" />
</TableColumns>
</Table>
</DemoBlock>

<DemoBlock Title="@Localizer["TablesColumnEditTemplateTitle"]" Introduction="@Localizer["TablesColumnEditTemplateIntro"]" Name="ColumnEditTemplate">
<section ignore>
<div>@((MarkupString)Localizer["TablesColumnEditTemplateDescription1"].Value)</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ public partial class TablesEdit
[NotNull]
private IEnumerable<Foo>? BindItems { get; set; }

[NotNull]
private IEnumerable<Foo>? KeepAddingItems { get; set; }

[NotNull]
private IEnumerable<Foo>? KeepAddingDrawerItems { get; set; }

private InsertRowMode InsertMode { get; set; } = InsertRowMode.Last;

private string? PlaceHolderString { get; set; }
Expand All @@ -58,10 +64,44 @@ protected override void OnInitialized()
CustomerDataService = new FooDataService<Foo>(FooLocalizer);
BindItems = Foo.GenerateFoo(FooLocalizer).Take(5).ToList();
PlaceHolderString ??= Localizer["TablesEditShowSearchPlaceHolderString"];

var keepAddingItems = Foo.GenerateFoo(FooLocalizer, 4);

// 数量列从 0 开始 便于观察连续新增时数量递增的效果
keepAddingItems.ForEach(i => i.Count = 0);
KeepAddingItems = keepAddingItems;

var keepAddingDrawerItems = Foo.GenerateFoo(FooLocalizer, 4);
keepAddingDrawerItems.ForEach(i => i.Count = 0);
KeepAddingDrawerItems = keepAddingDrawerItems;
}

private Task<Foo> OnAddAsync() => Task.FromResult(new Foo() { Id = GenerateId(), DateTime = DateTime.Now, Address = $"Custom address {DateTime.Now.Second}" });

private Task<Foo> OnKeepAddAsync() => Task.FromResult(Foo.Generate(FooLocalizer));

/// <summary>
/// 点击「保存并新增」按钮时基于上一条已保存数据创建下一条模型 数量 +10
/// </summary>
/// <param name="lastModel">刚刚保存成功的模型实例</param>
private static async Task<Foo> OnKeepAddingAsync(Foo lastModel)
{
// 模拟延时
await Task.Delay(10);

return new Foo()
{
Id = lastModel.Id + 1,
DateTime = lastModel.DateTime,
Name = lastModel.Name,
Address = lastModel.Address,
Complete = lastModel.Complete,
Education = lastModel.Education,
Hobby = lastModel.Hobby,
Count = lastModel.Count + 10
};
}

private int GenerateId()
{
var id = Items.Count;
Expand Down
5 changes: 5 additions & 0 deletions src/BootstrapBlazor.Server/Locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -5066,6 +5066,11 @@
"TablesEditTemplateIntro": "Set <code>ShowSearch</code> to show the query component",
"TablesEditTemplateTitle": "Tables with single table maintenance",
"TablesEditTitle": "Table",
"TablesKeepAddingDescription": "The next item is created by the <code>OnKeepAddingAsync</code> callback whose parameter is the model saved just now. In this example the <code>Count</code> of the new item is the <code>Count</code> of the previous item plus 10",
"TablesKeepAddingDrawerDescription": "The table below uses <code>EditMode.Drawer</code>, and keep adding behaves exactly the same as in dialog mode",
"TablesKeepAddingIntro": "Set <code>ShowKeepAddingButton</code> to show the <b>Save and Add</b> button in the <b>New</b> dialog/drawer footer. Clicking it saves the current item and keeps the UI open, and the next item is created by the <code>OnKeepAddingAsync</code> callback for continuous input",
"TablesKeepAddingTips": "Note: when the <code>OnKeepAddingAsync</code> callback is not set, the component falls back to the <code>OnAddAsync</code> callback, <code>CreateItemCallback</code> and the <code>AddAsync</code> method of the injected <code>IDataService</code> in order, which is the same as before, except that the <code>OnKeepAddingAsync</code> callback has the highest priority",
"TablesKeepAddingTitle": "Keep adding",
"TablesReadonlyColumnDescription": "Corresponding database calculated columns, or model read-only attributes",
"TablesReadonlyColumnIntro": "By setting <code>Field</code> and <code>FieldName</code>",
"TablesReadonlyColumnTips1": "Do not write <code>@bind-Field</code>. Read-only columns cannot be entered when <b>Add</b> or <b>Edit</b>",
Expand Down
5 changes: 5 additions & 0 deletions src/BootstrapBlazor.Server/Locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -5066,6 +5066,11 @@
"TablesEditTemplateIntro": "通过设置 <code>EditTemplate</code> 自定义编辑弹窗,<code>10.0.1</code> 版本后支持联动功能",
"TablesEditTemplateTitle": "具有单表维护功能的表格",
"TablesEditTitle": "Table 表格",
"TablesKeepAddingDescription": "下一条数据由 <code>OnKeepAddingAsync</code> 回调创建,回调参数为刚刚保存成功的模型实例;本示例中新数据的 <code>Count</code> 为上一笔数据的 <code>Count</code> 加 10",
"TablesKeepAddingDrawerDescription": "下表中 <code>EditMode</code> 为 <code>Drawer</code>,连续新增在抽屉模式下具有与弹窗模式完全一致的行为",
"TablesKeepAddingIntro": "设置 <code>ShowKeepAddingButton</code> 在 <b>新建</b> 弹窗/抽屉 Footer 中显示 <b>保存并新增</b> 按钮,点击后先保存当前数据并保持界面打开,下一条数据由 <code>OnKeepAddingAsync</code> 回调创建以便连续录入",
"TablesKeepAddingTips": "注意:未设置 <code>OnKeepAddingAsync</code> 回调时,组件依次回落调用 <code>OnAddAsync</code>、<code>CreateItemCallback</code> 以及注入服务 <code>IDataService</code> 的 <code>AddAsync</code> 方法,此处知识点与以前一致,仅优先执行 <code>OnKeepAddingAsync</code> 回调",
"TablesKeepAddingTitle": "连续新增",
"TablesReadonlyColumnDescription": "对应数据库计算列,或者模型只读属性",
"TablesReadonlyColumnIntro": "通过设置 <code>Field</code> 与 <code>FieldName</code> 即可",
"TablesReadonlyColumnTips1": "不要写 <code>@bind-Field</code> 只读列在 <b>新建</b> 或者 <b>编辑</b> 时均无法录入",
Expand Down
2 changes: 1 addition & 1 deletion src/BootstrapBlazor/BootstrapBlazor.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<Version>11.0.1-beta02</Version>
<Version>11.0.1-beta03</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
36 changes: 34 additions & 2 deletions src/BootstrapBlazor/Components/Dialog/EditDialog.razor
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
@inherits DialogBase<TModel>
@attribute [BootstrapModuleAutoLoader("Dialog/EditDialog.razor.js", AutoInvokeInit = false, AutoInvokeDispose = false)]

<ValidateForm Model="@Model" OnValidSubmit="@OnValidSubmitAsync" LabelWidth="@LabelWidth"
<ValidateForm Model="@_currentModel" OnValidSubmit="@OnValidSubmitAsync"
OnInvalidSubmit="@OnInvalidSubmitAsync" LabelWidth="@LabelWidth"
OnFieldValueChanged="OnFieldValueChanged"
DisableAutoSubmitFormByEnter="@DisableAutoSubmitFormByEnter">
<CascadingValue Value="ItemChangedType" IsFixed="true">
@if (BodyTemplate != null)
{
<div class="form-body">
@BodyTemplate(Model)
@BodyTemplate(_currentModel)
</div>
<div class="form-footer">
@RenderFooter
Expand All @@ -32,3 +33,34 @@
</div>
</CascadingValue>
</ValidateForm>

@code {
/// <summary>
/// <para lang="zh">获得 编辑弹窗 Footer 内容</para>
/// <para lang="en">Gets the Footer content of the edit dialog</para>
/// </summary>
private RenderFragment RenderFooter => @<text>
@if (FooterTemplate != null)
{
@FooterTemplate(_currentModel)
}
else
{
@if (!IsTracking)
{
<DialogCloseButton Icon="@CloseButtonIcon" Text="@CloseButtonText" OnClickWithoutRender="OnCloseAsync" />
}

@* 「保存并新增」先于主保存按钮渲染 作为表单默认按钮 未禁用回车提交时按「保存并新增」处理 *@
@if (IsKeepAdding)
{
<Button Color="@KeepAddingButtonColor" Icon="@KeepAddingButtonIcon" Text="@KeepAddingButtonText"
ButtonType="ButtonType.Submit" IsAsync="true" OnClick="OnKeepAddingClick" />
}

@* 主保存按钮 逻辑与原有保存按钮一致 保存成功后关闭弹窗 *@
<Button Color="Color.Primary" Icon="@SaveButtonIcon" Text="@SaveButtonText"
ButtonType="ButtonType.Submit" IsAsync="true" OnClick="@OnSaveClick" />
}
</text>;
}
Loading
Loading