From cb4bd6f7007f1eb4964c65ae757d10eb212c3e2e Mon Sep 17 00:00:00 2001 From: Argo-AsicoTech Date: Fri, 20 Dec 2024 10:44:26 +0800 Subject: [PATCH 1/7] =?UTF-8?q?refactor:=20=E5=A2=9E=E5=8A=A0=20LookupServ?= =?UTF-8?q?ice=20=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/EditorForm/EditorForm.razor | 9 +++---- .../Components/EditorForm/EditorForm.razor.cs | 26 +------------------ .../Components/Table/Table.razor.cs | 10 ++----- .../Extensions/IEditorItemExtensions.cs | 8 ++++++ src/BootstrapBlazor/Utils/Utility.cs | 3 ++- 5 files changed, 16 insertions(+), 40 deletions(-) diff --git a/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor b/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor index a3a6de869f1..c5aef9d2caf 100644 --- a/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor +++ b/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor @@ -40,12 +40,9 @@ } - @if (!_inited) - { -
- -
- } +
+ +
@code diff --git a/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor.cs b/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor.cs index 0b59bac6ca0..356c7668eec 100644 --- a/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor.cs +++ b/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor.cs @@ -191,7 +191,6 @@ public partial class EditorForm : IShowLabel .GroupBy(i => i.GroupOrder).OrderBy(i => i.Key) .Select(i => new KeyValuePair>(i.First().GroupName!, i.OrderBy(x => x.Order))); - private bool _inited; private List? _itemsCache; private List RenderItems @@ -238,29 +237,6 @@ protected override void OnParametersSet() _itemsCache = null; } - /// - /// - /// - /// - protected override async Task OnAfterRenderAsync(bool firstRender) - { - await base.OnAfterRenderAsync(firstRender); - - if (firstRender) - { - foreach (var item in RenderItems) - { - if (item.Lookup == null && !string.IsNullOrEmpty(item.LookupServiceKey)) - { - var lookupServcie = item.LookupService ?? LookupService; - item.Lookup = await lookupServcie.GetItemsAsync(item.LookupServiceKey, item.LookupServiceData); - } - } - _inited = true; - StateHasChanged(); - } - } - private List GetRenderItems() { var items = new List(); @@ -315,7 +291,7 @@ private RenderFragment AutoGenerateTemplate(IEditorItem item) => builder => else { item.PlaceHolder ??= PlaceHolderText; - builder.CreateComponentByFieldType(this, item, Model, ItemChangedType, IsSearch.Value); + builder.CreateComponentByFieldType(this, item, Model, ItemChangedType, IsSearch.Value, item.GetLookupService(LookupService)); } }; diff --git a/src/BootstrapBlazor/Components/Table/Table.razor.cs b/src/BootstrapBlazor/Components/Table/Table.razor.cs index 2921c619372..17b7af3f915 100644 --- a/src/BootstrapBlazor/Components/Table/Table.razor.cs +++ b/src/BootstrapBlazor/Components/Table/Table.razor.cs @@ -1141,12 +1141,6 @@ private async Task ProcessFirstRender() Columns.Clear(); Columns.AddRange(cols.OrderFunc()); - // 准备 Lookup 数据 - foreach (var column in Columns) - { - column.Lookup ??= await LookupService.GetItemsAsync(column.LookupServiceKey, column.LookupServiceData); - } - // 查看是否开启列宽序列化 _clientColumnWidths = await ReloadColumnWidthFromBrowserAsync(); ResetColumnWidth(); @@ -1329,7 +1323,7 @@ RenderFragment RenderTemplate() => col.Template == null : col.Template(item); RenderFragment RenderEditTemplate() => col.EditTemplate == null - ? new RenderFragment(builder => builder.CreateComponentByFieldType(this, col, item, changedType, false)) + ? new RenderFragment(builder => builder.CreateComponentByFieldType(this, col, item, changedType, false, col.GetLookupService(LookupService))) : col.EditTemplate(item); } @@ -1371,7 +1365,7 @@ void SetDynamicEditTemplate() parameters.Add(new(nameof(ValidateBase.OnValueChanged), onValueChanged.Invoke(d, col, (model, column, val) => DynamicContext.OnValueChanged(model, column, val)))); col.ComponentParameters = parameters; } - builder.CreateComponentByFieldType(this, col, row, changedType, false); + builder.CreateComponentByFieldType(this, col, row, changedType, false, col.GetLookupService(LookupService)); }; } diff --git a/src/BootstrapBlazor/Extensions/IEditorItemExtensions.cs b/src/BootstrapBlazor/Extensions/IEditorItemExtensions.cs index 29b81570756..004bfa74c85 100644 --- a/src/BootstrapBlazor/Extensions/IEditorItemExtensions.cs +++ b/src/BootstrapBlazor/Extensions/IEditorItemExtensions.cs @@ -110,4 +110,12 @@ bool ComplexCanWrite() internal static bool GetIgnore(this IEditorItem col) => col.Ignore ?? false; internal static bool GetReadonly(this IEditorItem col) => col.Readonly ?? false; + + /// + /// 获得 ILookupService 实例 + /// + /// + /// + /// + public static ILookupService GetLookupService(this IEditorItem item, ILookupService service) => item.LookupService ?? service; } diff --git a/src/BootstrapBlazor/Utils/Utility.cs b/src/BootstrapBlazor/Utils/Utility.cs index b00a0c2d07e..033f6a198bc 100644 --- a/src/BootstrapBlazor/Utils/Utility.cs +++ b/src/BootstrapBlazor/Utils/Utility.cs @@ -459,7 +459,8 @@ public static void CreateDisplayByFieldType(this RenderTreeBuilder builder, IEdi /// /// /// - public static void CreateComponentByFieldType(this RenderTreeBuilder builder, ComponentBase component, IEditorItem item, object model, ItemChangedType changedType = ItemChangedType.Update, bool isSearch = false) + /// + public static void CreateComponentByFieldType(this RenderTreeBuilder builder, ComponentBase component, IEditorItem item, object model, ItemChangedType changedType = ItemChangedType.Update, bool isSearch = false, ILookupService? lookUpService = null) { var fieldType = item.PropertyType; var fieldName = item.GetFieldName(); From f14c6529f69a1f50165b3a83cd3f1a28236052a5 Mon Sep 17 00:00:00 2001 From: Argo-AsicoTech Date: Fri, 20 Dec 2024 11:17:32 +0800 Subject: [PATCH 2/7] =?UTF-8?q?refactor:=20=E5=A2=9E=E5=8A=A0=20LookupServ?= =?UTF-8?q?ice=20=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Select/SelectBase.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/BootstrapBlazor/Components/Select/SelectBase.cs b/src/BootstrapBlazor/Components/Select/SelectBase.cs index afe7b453cc3..6282372aa78 100644 --- a/src/BootstrapBlazor/Components/Select/SelectBase.cs +++ b/src/BootstrapBlazor/Components/Select/SelectBase.cs @@ -53,6 +53,24 @@ public abstract class SelectBase : PopoverSelectBase [Parameter] public RenderFragment? GroupItemTemplate { get; set; } + /// + /// 获得/设置 服务实例 + /// + [Parameter] + public ILookupService? LookupService { get; set; } + + /// + /// 获得/设置 服务获取 Lookup 数据集合键值 常用于外键自动转换为名称操作,可以通过 传递自定义数据 + /// + [Parameter] + public string? LookupServiceKey { get; set; } + + /// + /// 获得/设置 服务获取 Lookup 数据集合键值自定义数据,通过 指定键值 + /// + [Parameter] + public object? LookupServiceData { get; set; } + /// /// 获得/设置 IIconTheme 服务实例 /// From bcc5b73696be004976390d58edece5c148cdbb72 Mon Sep 17 00:00:00 2001 From: Argo-AsicoTech Date: Fri, 20 Dec 2024 11:17:44 +0800 Subject: [PATCH 3/7] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E6=89=A9?= =?UTF-8?q?=E5=B1=95=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor/Extensions/IEditorItemExtensions.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/BootstrapBlazor/Extensions/IEditorItemExtensions.cs b/src/BootstrapBlazor/Extensions/IEditorItemExtensions.cs index 004bfa74c85..2071082215a 100644 --- a/src/BootstrapBlazor/Extensions/IEditorItemExtensions.cs +++ b/src/BootstrapBlazor/Extensions/IEditorItemExtensions.cs @@ -12,6 +12,13 @@ namespace BootstrapBlazor.Components; /// public static class IEditorItemExtensions { + /// + /// 判断当前 IEditorItem 实例是否为 Lookup 类型 + /// + /// + /// + public static bool IsLookup(this IEditorItem item) => item.Lookup != null || item.LookupService != null || !string.IsNullOrEmpty(item.LookupServiceKey); + /// /// 判断当前 IEditorItem 实例是否可以编辑 /// From f66e6124b6a79257f09aac18f536baad6a46c61d Mon Sep 17 00:00:00 2001 From: Argo-AsicoTech Date: Fri, 20 Dec 2024 11:18:09 +0800 Subject: [PATCH 4/7] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=20LookupService?= =?UTF-8?q?=20=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor/Utils/Utility.cs | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/BootstrapBlazor/Utils/Utility.cs b/src/BootstrapBlazor/Utils/Utility.cs index 033f6a198bc..0bd52e56791 100644 --- a/src/BootstrapBlazor/Utils/Utility.cs +++ b/src/BootstrapBlazor/Utils/Utility.cs @@ -469,8 +469,7 @@ public static void CreateComponentByFieldType(this RenderTreeBuilder builder, Co var fieldValue = GenerateValue(model, fieldName); var fieldValueChanged = GenerateValueChanged(component, model, fieldName, fieldType); var valueExpression = GenerateValueExpression(model, fieldName, fieldType); - var lookup = item.Lookup; - var componentType = item.ComponentType ?? GenerateComponentType(fieldType, item.Rows != 0, lookup); + var componentType = item.ComponentType ?? GenerateComponentType(item); builder.OpenComponent(0, componentType); if (componentType.IsSubclassOf(typeof(ValidateBase<>).MakeGenericType(fieldType))) { @@ -514,20 +513,22 @@ public static void CreateComponentByFieldType(this RenderTreeBuilder builder, Co } // Nullable - if (item.ComponentType == typeof(Select) && fieldType == typeof(bool?) && lookup == null && item.Items == null) + if (item.ComponentType == typeof(Select) && fieldType == typeof(bool?) && !item.IsLookup() && item.Items == null) { builder.AddAttribute(100, nameof(Select.Items), GetNullableBoolItems(model, fieldName)); } // Lookup - if (lookup != null && item.Items == null) + if (item.IsLookup() && item.Items == null) { builder.AddAttribute(110, nameof(Select.ShowSearch), item.ShowSearchWhenSelect); - builder.AddAttribute(120, nameof(Select.Items), lookup.Clone()); + builder.AddAttribute(120, nameof(Select.LookupService), item.LookupService); + builder.AddAttribute(121, nameof(Select.LookupServiceKey), item.LookupServiceKey); + builder.AddAttribute(122, nameof(Select.LookupServiceData), item.LookupServiceData); builder.AddAttribute(130, nameof(Select.StringComparison), item.LookupStringComparison); } - // 增加非枚举类,手动设定 ComponentType 为 Select 并且 Data 有值 自动生成下拉框 + // 增加非枚举类,手动设定 ComponentType 为 Select 并且 Items 有值 自动生成下拉框 if (item.Items != null && item.ComponentType == typeof(Select<>).MakeGenericType(fieldType)) { builder.AddAttribute(140, nameof(Select.Items), item.Items.Clone()); @@ -616,15 +617,13 @@ object ComplexPropertyValueExpression() /// /// 通过指定类型生成组件类型 /// - /// - /// 是否为 TextArea 组件 - /// - /// - private static Type GenerateComponentType(Type fieldType, bool hasRows, IEnumerable? lookup) + /// + private static Type GenerateComponentType(IEditorItem item) { + var fieldType = item.PropertyType; Type? ret = null; var type = (Nullable.GetUnderlyingType(fieldType) ?? fieldType); - if (type.IsEnum || lookup != null) + if (type.IsEnum || item.IsLookup()) { ret = typeof(Select<>).MakeGenericType(fieldType); } @@ -650,7 +649,7 @@ private static Type GenerateComponentType(Type fieldType, bool hasRows, IEnumera } else if (fieldType == typeof(string)) { - ret = hasRows ? typeof(Textarea) : typeof(BootstrapInput<>).MakeGenericType(typeof(string)); + ret = item.Rows > 0 ? typeof(Textarea) : typeof(BootstrapInput<>).MakeGenericType(typeof(string)); } return ret ?? typeof(BootstrapInput<>).MakeGenericType(fieldType); } From 2578bb4cce7933f04599d5542457deaab4324bee Mon Sep 17 00:00:00 2001 From: Argo-AsicoTech Date: Fri, 20 Dec 2024 11:43:12 +0800 Subject: [PATCH 5/7] =?UTF-8?q?test:=20=E6=8F=90=E9=AB=98=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E8=A6=86=E7=9B=96=E7=8E=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/UnitTest/Components/EditorFormTest.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/UnitTest/Components/EditorFormTest.cs b/test/UnitTest/Components/EditorFormTest.cs index 120ccbee6eb..b6a07f9cfce 100644 --- a/test/UnitTest/Components/EditorFormTest.cs +++ b/test/UnitTest/Components/EditorFormTest.cs @@ -443,6 +443,9 @@ public async Task LookupServiceKey_Ok() var lookup = await lookupService.GetItemsAsync("FooLookup", ""); Assert.NotNull(lookup); Assert.Equal(lookup.Count(), select.Instance.Items.Count()); + + lookup = await lookupService.GetItemsAsync(null, ""); + Assert.Null(lookup); } [Fact] From 2069cf34767f8679ef24be261ea8f92f7c4de5bf Mon Sep 17 00:00:00 2001 From: Argo-AsicoTech Date: Fri, 20 Dec 2024 11:43:29 +0800 Subject: [PATCH 6/7] =?UTF-8?q?refactor:=20=E5=A2=9E=E5=8A=A0=20LookupServ?= =?UTF-8?q?ice=20=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Select/Select.razor.cs | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/BootstrapBlazor/Components/Select/Select.razor.cs b/src/BootstrapBlazor/Components/Select/Select.razor.cs index dc6b1eb871f..88b91588a09 100644 --- a/src/BootstrapBlazor/Components/Select/Select.razor.cs +++ b/src/BootstrapBlazor/Components/Select/Select.razor.cs @@ -284,7 +284,10 @@ private SelectedItem? SelectedRow private List GetRowsByItems() { var items = new List(); - items.AddRange(Items); + if (Items != null) + { + items.AddRange(Items); + } items.AddRange(_children); return items; } @@ -306,11 +309,20 @@ protected override void OnParametersSet() { base.OnParametersSet(); - Items ??= []; PlaceHolder ??= Localizer[nameof(PlaceHolder)]; NoSearchDataText ??= Localizer[nameof(NoSearchDataText)]; DropdownIcon ??= IconTheme.GetIconByKey(ComponentIcons.SelectDropdownIcon); ClearIcon ??= IconTheme.GetIconByKey(ComponentIcons.SelectClearIcon); + } + + /// + /// + /// + protected override async Task OnParametersSetAsync() + { + await base.OnParametersSetAsync(); + + Items ??= await GetItemsAsync(); // 内置对枚举类型的支持 if (!Items.Any() && ValueType.IsEnum()) @@ -338,6 +350,16 @@ protected override async Task OnAfterRenderAsync(bool firstRender) } } + private async Task> GetItemsAsync() + { + IEnumerable? items = null; + if (LookupService != null) + { + items = await LookupService.GetItemsByKeyAsync(LookupServiceKey, LookupServiceData); + } + return items ?? []; + } + /// /// 获得/设置 数据总条目 /// From ee1f5f5f33c3a2da3059878ab2b140336630228c Mon Sep 17 00:00:00 2001 From: Argo-AsicoTech Date: Fri, 20 Dec 2024 11:43:52 +0800 Subject: [PATCH 7/7] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=20Select=20?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E5=AF=B9=20LookupService=20=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E8=B5=8B=E5=80=BC=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor/Utils/Utility.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/BootstrapBlazor/Utils/Utility.cs b/src/BootstrapBlazor/Utils/Utility.cs index 0bd52e56791..69a19036d59 100644 --- a/src/BootstrapBlazor/Utils/Utility.cs +++ b/src/BootstrapBlazor/Utils/Utility.cs @@ -459,8 +459,8 @@ public static void CreateDisplayByFieldType(this RenderTreeBuilder builder, IEdi /// /// /// - /// - public static void CreateComponentByFieldType(this RenderTreeBuilder builder, ComponentBase component, IEditorItem item, object model, ItemChangedType changedType = ItemChangedType.Update, bool isSearch = false, ILookupService? lookUpService = null) + /// + public static void CreateComponentByFieldType(this RenderTreeBuilder builder, ComponentBase component, IEditorItem item, object model, ItemChangedType changedType = ItemChangedType.Update, bool isSearch = false, ILookupService? lookupService = null) { var fieldType = item.PropertyType; var fieldName = item.GetFieldName(); @@ -522,7 +522,7 @@ public static void CreateComponentByFieldType(this RenderTreeBuilder builder, Co if (item.IsLookup() && item.Items == null) { builder.AddAttribute(110, nameof(Select.ShowSearch), item.ShowSearchWhenSelect); - builder.AddAttribute(120, nameof(Select.LookupService), item.LookupService); + builder.AddAttribute(120, nameof(Select.LookupService), lookupService); builder.AddAttribute(121, nameof(Select.LookupServiceKey), item.LookupServiceKey); builder.AddAttribute(122, nameof(Select.LookupServiceData), item.LookupServiceData); builder.AddAttribute(130, nameof(Select.StringComparison), item.LookupStringComparison);