Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Formatter): CreateDisplayByFieldType method supports Formatter callback #2896

Merged
merged 6 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -108,7 +108,7 @@ public class AutoGenerateColumnAttribute : AutoGenerateBaseAttribute, ITableColu
/// <summary>
/// 获得/设置 列格式化回调委托
/// </summary>
public Func<object?, Task<string>>? Formatter { get; set; }
public Func<object?, Task<string?>>? Formatter { get; set; }

/// <summary>
/// 获得/设置 编辑模板
Expand Down
2 changes: 1 addition & 1 deletion src/BootstrapBlazor/Components/Display/Display.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public partial class Display<TValue>
/// 获得/设置 异步格式化字符串
/// </summary>
[Parameter]
public Func<TValue, Task<string>>? FormatterAsync { get; set; }
public Func<TValue, Task<string?>>? FormatterAsync { get; set; }

/// <summary>
/// 获得/设置 格式化字符串 如时间类型设置 yyyy-MM-dd
Expand Down
2 changes: 1 addition & 1 deletion src/BootstrapBlazor/Components/Table/ITableColumn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public interface ITableColumn : IEditorItem
/// <summary>
/// 获得/设置 列格式化回调委托
/// </summary>
Func<object?, Task<string>>? Formatter { get; set; }
Func<object?, Task<string?>>? Formatter { get; set; }

/// <summary>
/// 获得/设置 文字对齐方式 默认为 Alignment.None
Expand Down
29 changes: 11 additions & 18 deletions src/BootstrapBlazor/Components/Table/InternalTableColumn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@

namespace BootstrapBlazor.Components;

class InternalTableColumn : ITableColumn
/// <summary>
/// 构造函数
/// </summary>
/// <param name="fieldName">字段名称</param>
/// <param name="fieldType">字段类型</param>
/// <param name="fieldText">显示文字</param>
class InternalTableColumn(string fieldName, Type fieldType, string? fieldText = null) : ITableColumn
{
private string FieldName { get; }
private string FieldName { get; } = fieldName;

public bool Sortable { get; set; }

Expand Down Expand Up @@ -72,13 +78,13 @@ class InternalTableColumn : ITableColumn
/// </summary>
public string? PlaceHolder { get; set; }

public Func<object?, Task<string>>? Formatter { get; set; }
public Func<object?, Task<string?>>? Formatter { get; set; }

public Alignment Align { get; set; }

public bool ShowTips { get; set; }

public Type PropertyType { get; }
public Type PropertyType { get; } = fieldType;

public bool Editable { get; set; } = true;

Expand All @@ -89,7 +95,7 @@ class InternalTableColumn : ITableColumn
public int Rows { get; set; }

[NotNull]
public string? Text { get; set; }
public string? Text { get; set; } = fieldText;

public RenderFragment<object>? EditTemplate { get; set; }

Expand Down Expand Up @@ -188,19 +194,6 @@ class InternalTableColumn : ITableColumn
/// </summary>
public bool IsMarkupString { get; set; }

/// <summary>
/// 构造函数
/// </summary>
/// <param name="fieldName">字段名称</param>
/// <param name="fieldType">字段类型</param>
/// <param name="fieldText">显示文字</param>
public InternalTableColumn(string fieldName, Type fieldType, string? fieldText = null)
{
FieldName = fieldName;
PropertyType = fieldType;
Text = fieldText;
}

public string GetDisplayName() => Text;

public string GetFieldName() => FieldName;
Expand Down
4 changes: 2 additions & 2 deletions src/BootstrapBlazor/Components/Table/TableColumn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ public class TableColumn<TItem, TType> : BootstrapComponentBase, ITableColumn
/// 获得/设置 列格式化回调委托
/// </summary>
[Parameter]
public Func<object?, Task<string>>? Formatter { get; set; }
public Func<object?, Task<string?>>? Formatter { get; set; }

/// <summary>
/// 获得/设置 显示模板
Expand Down Expand Up @@ -480,7 +480,7 @@ public string GetFieldName()
express = member.Expression;
}

if (fields.Any())
if (fields.Count != 0)
{
fields.Reverse();
FieldName = string.Join(".", fields);
Expand Down
2 changes: 1 addition & 1 deletion src/BootstrapBlazor/Components/Upload/SingleUploadBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ protected virtual List<UploadFile> GetUploadFiles()
var ret = new List<UploadFile>();
if (IsSingle)
{
if (DefaultFileList?.Any() ?? false)
if (DefaultFileList != null && DefaultFileList.Count != 0)
{
ret.Add(DefaultFileList.First());
}
Expand Down
26 changes: 24 additions & 2 deletions src/BootstrapBlazor/Services/CacheManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ public static Func<IEnumerable<T>, List<string>, IEnumerable<T>> GetSortListFunc
#region Format
public static Func<object, string, IFormatProvider?, string> GetFormatInvoker(Type type)
{
var cacheKey = $"{nameof(GetFormatInvoker)}-{nameof(GetFormatLambda)}-{type.FullName}";
var cacheKey = $"{nameof(GetFormatInvoker)}-{type.FullName}";
return Instance.GetOrCreate(cacheKey, entry =>
{
entry.SetDynamicAssemblyPolicy(type);
Expand Down Expand Up @@ -669,7 +669,7 @@ public static Func<IEnumerable<T>, List<string>, IEnumerable<T>> GetSortListFunc

public static Func<object, IFormatProvider?, string> GetFormatProviderInvoker(Type type)
{
var cacheKey = $"{nameof(GetFormatProviderInvoker)}-{nameof(GetFormatProviderLambda)}-{type.FullName}";
var cacheKey = $"{nameof(GetFormatProviderInvoker)}-{type.FullName}";
return Instance.GetOrCreate(cacheKey, entry =>
{
entry.SetDynamicAssemblyPolicy(type);
Expand Down Expand Up @@ -697,5 +697,27 @@ public static Func<IEnumerable<T>, List<string>, IEnumerable<T>> GetSortListFunc
return Expression.Lambda<Func<object, IFormatProvider?, string>>(body, exp_p1, exp_p2);
}
}

public static object GetFormatterInvoker(Type type, Func<object?, Task<string?>> formatter)
{
var cacheKey = $"{nameof(GetFormatterInvoker)}-{type.FullName}";
var invoker = Instance.GetOrCreate(cacheKey, entry =>
{
entry.SetDynamicAssemblyPolicy(type);
return GetFormatterInvokerLambda(type).Compile();
});
return invoker(formatter);

static Expression<Func<Func<object?, Task<string?>>, object>> GetFormatterInvokerLambda(Type type)
{
var method = typeof(CacheManager).GetMethod(nameof(InvokeFormatterAsync), BindingFlags.Static | BindingFlags.NonPublic)!.MakeGenericMethod(type);
var exp_p1 = Expression.Parameter(typeof(Func<object?, Task<string?>>));
var body = Expression.Call(null, method, exp_p1);
return Expression.Lambda<Func<Func<object?, Task<string?>>, object>>(body, exp_p1);
}
}

private static Func<TType, Task<string?>> InvokeFormatterAsync<TType>(Func<object?, Task<string?>> formatter) => new(v => formatter(v));

#endregion
}
9 changes: 6 additions & 3 deletions src/BootstrapBlazor/Utils/Utility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,11 @@ public static void CreateDisplayByFieldType(this RenderTreeBuilder builder, IEdi
builder.AddAttribute(4, nameof(Display<string>.ShowLabelTooltip), item.ShowLabelTooltip);
if (item is ITableColumn col)
{
// TODO: 暂时不支持 Formatter 逻辑
if (!string.IsNullOrEmpty(col.FormatString))
if (col.Formatter != null)
{
builder.AddAttribute(5, nameof(Display<string>.FormatterAsync), CacheManager.GetFormatterInvoker(fieldType, col.Formatter));
}
else if (!string.IsNullOrEmpty(col.FormatString))
{
builder.AddAttribute(5, nameof(Display<string>.FormatString), col.FormatString);
}
Expand Down Expand Up @@ -528,7 +531,7 @@ public static void CreateComponentByFieldType(this RenderTreeBuilder builder, Co
GroupName = d.GroupName
}).ToList();

private static object? GenerateValue(object model, string fieldName) => Utility.GetPropertyValue<object, object?>(model, fieldName);
private static object? GenerateValue(object model, string fieldName) => GetPropertyValue<object, object?>(model, fieldName);

/// <summary>
/// 通过指定类型实例获取属性 Lambda 表达式
Expand Down
2 changes: 1 addition & 1 deletion test/UnitTest/Misc/MockTableColumn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ internal class MockTableColumn : ITableColumn

public string? FormatString { get; set; }

public Func<object?, Task<string>>? Formatter { get; set; }
public Func<object?, Task<string?>>? Formatter { get; set; }

public Alignment Align { get; set; }

Expand Down
2 changes: 0 additions & 2 deletions test/UnitTest/Utils/JSModuleTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,6 @@ public ValueTask<TValue> InvokeAsync<TValue>(string identifier, CancellationToke
{
return ValueTask.FromResult<TValue>(default!);
}

public ValueTask InvokeVoidAsync_JSDisconnected_Test() => throw new JSDisconnectedException("Test");
}

private class MockJSDisconnectedObjectReference : IJSObjectReference
Expand Down
28 changes: 27 additions & 1 deletion test/UnitTest/Utils/UtilityTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,31 @@ public void CreateDisplayByFieldType_FormatString()
Assert.Equal($"<div class=\"form-control is-display\">{dt:yyyy}</div>", cut.Markup);
}

[Fact]
public void CreateDisplayByFieldType_Formatter()
{
var dt = DateTime.Now;
var editor = new MockTableColumn("DateTime", typeof(DateTime?))
{
Formatter = new Func<object?, Task<string?>>(async v =>
{
var ret = "";
await Task.Delay(1);
if (v is DateTime d)
{
ret = $"{d:yyyyMMddhhmmss}";
}
return ret;
})
};
var fragment = new RenderFragment(builder => builder.CreateDisplayByFieldType(editor, new Foo() { DateTime = dt }));
var cut = Context.Render(builder => builder.AddContent(0, fragment));
cut.WaitForAssertion(() =>
{
Assert.Equal($"<div class=\"form-control is-display\">{dt:yyyyMMddhhmmss}</div>", cut.Markup);
});
}

[Fact]
public void CreateComponentByFieldType_Ok()
{
Expand Down Expand Up @@ -498,7 +523,7 @@ public void ConvertValueToString_Ok()
var actual1 = Utility.ConvertValueToString(val);
Assert.Equal("1.1,2,3.1", actual1);

var items = new List<SelectedItem>() { new SelectedItem("Test1", "Test1"), new SelectedItem("Test2", "Test2") };
var items = new List<SelectedItem>() { new("Test1", "Test1"), new("Test2", "Test2") };
var actual2 = Utility.ConvertValueToString(items);
Assert.Equal("Test1,Test2", actual2);

Expand Down Expand Up @@ -697,6 +722,7 @@ private enum TestEnum
Address
}

[AttributeUsage(AttributeTargets.Property)]
private class CatKeyAttribute : Attribute
{

Expand Down
Loading