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/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 ?? [];
+ }
+
///
/// 获得/设置 数据总条目
///
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 服务实例
///
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..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 实例是否可以编辑
///
@@ -110,4 +117,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..69a19036d59 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();
@@ -468,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)))
{
@@ -513,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), 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());
@@ -615,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);
}
@@ -649,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);
}
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]