Hayou.Abp.DynamicFieldManagement.Domain
0.2.0
dotnet add package Hayou.Abp.DynamicFieldManagement.Domain --version 0.2.0
NuGet\Install-Package Hayou.Abp.DynamicFieldManagement.Domain -Version 0.2.0
<PackageReference Include="Hayou.Abp.DynamicFieldManagement.Domain" Version="0.2.0" />
<PackageVersion Include="Hayou.Abp.DynamicFieldManagement.Domain" Version="0.2.0" />
<PackageReference Include="Hayou.Abp.DynamicFieldManagement.Domain" />
paket add Hayou.Abp.DynamicFieldManagement.Domain --version 0.2.0
#r "nuget: Hayou.Abp.DynamicFieldManagement.Domain, 0.2.0"
#:package Hayou.Abp.DynamicFieldManagement.Domain@0.2.0
#addin nuget:?package=Hayou.Abp.DynamicFieldManagement.Domain&version=0.2.0
#tool nuget:?package=Hayou.Abp.DynamicFieldManagement.Domain&version=0.2.0
动态属性模块
动态属性模块可实现对现有实体添加动态字段的功能,并能在按照一定的约定配置后方便的管理动态字段。
用法:
1、添加相应的模块引用,并在webHost项目模块中添加模块依赖
为 webHost 模块添加以下模块的引用,
Hayou.Abp.DynaimcFieldManagement.Application
Hayou.Abp.DynaimcFieldManagement.Domain
Hayou.Abp.DynaimcFieldManagement.EntityFrameworkCore
Hayou.Abp.DynaimcFieldManagement.Web
Hayou.Abp.AspNetCore.Mvc.UI.RazorPages.DynamicField //在需要引入动态字段的UI界面所在的Web项目中引用
添加模块依赖
[DependsOn(
// ABP DynamicField packages
typeof(HayouAbpDynamicFieldManagementApplicationModule),
typeof(HayouAbpDynamicFieldManagementHttpApiModule),
typeof(HayouAbpDynamicFieldManagementEntityFrameworkCoreModule),
typeof(HayouAbpDynamicFieldManagementWebModule),
...
)]
public class xxxWebUnifiedModule : AbpModule{
}
2、在
DemoDbContext的OnModelCreating方法中添加实体配置builder.ConfigureDynamicFieldManagement();
public class DemoDbContext : AbpDbContext<DemoDbContext>
{
protected override void OnModelCreating(ModelBuilder builder)
{
/* Configure your own entities here */
builder.ConfigureDynamicFieldManagement();
}
}
在程序包管理控制台里添加 迁移文件,并执行迁移
add-migration Add-DynamicFieldEntities
update-database
这样在项目中就可以定义和管理动态字段了。
3、需要添加动态属性的实体和 dto 需要继承自
IHasDynamicFields。
//实体定义
[Display(Name = "图书")]
public class Book : AuditedEntity<Guid>, IMultiTenant, IHasDynamicFields
{
public ExtraPropertyDictionary ExtraProperties { get; set; } = new();
}
//Dto定义
public class BookDto : AuditedEntityDto<Guid>, IMultiTenant, IHasDynamicFields
{
public ExtraPropertyDictionary ExtraProperties { get; set; } = new();
}
只有继承了IHasDynamicFields 和基类继承自 Entity<Guid> 的实体,才可以配置动态字段。为实体类添加 Display特性,可使用显示特性来为实体提供更友好的名称。
4、在服务层对
GetListAsync、GetAsync方法添加对动态字段的填充(可选)
public override async Task<PagedResultDto<BookDto>> GetListAsync(PagedAndSortedResultRequestDto input)
{
var query = await CreateFilteredQueryAsync(input);
...
var entities = await AsyncExecuter.ToListAsync(query);
//填充动态字段
var dynamicFieldManagement = LazyServiceProvider.GetRequiredService<IDynamicFieldManager<Book>>();
entities = await dynamicFieldManagement?.FillEntityDynamicValuesAsync(entities, true);
var dtos = await MapToGetListOutputDtosAsync(entities);
return new PagedResultDto<BookDto>(
totalCount,
dtos
);
}
public override async Task<BookDto> GetAsync(Guid id)
{
var entity = await Repository.GetAsync(id);
//填充动态字段
var dynamicFieldManagement = LazyServiceProvider.GetRequiredService<IDynamicFieldManager<Book>>();
entity = await dynamicFieldManagement?.FillEntityDynamicValuesAsync(entity);
return await MapToGetOutputDtoAsync(entity);
}
在Asp.net Razor 页面UI层的使用:
5、在
Index.cshtml页面代码中添加动态属性脚本的引用(可选):
@section scripts {
<abp-script-bundle name="@(typeof(IndexModel).FullName)">
<abp-script src="/Pages/Book/Index.cshtml.js" />
</abp-script-bundle>
<script src="/Abp/DynamicFieldScript"></script>
}
这样可以提前缓存动态字段的定义到浏览器缓存,以便在列表里能显示这些动态字段列。
6、在
Index.cshtml.js脚本代码中添加动态属性列的定义(可选):
var columnDefs = [ ... ];
columnDefs = abp.dynamicFields.dynamicFieldColumnDef("book", columnDefs, ['F01', 'F02']);// 只显示 F01和F02两个动态字段
//columnDefs = abp.dynamicFields.dynamicFieldColumnDef("book", columnDefs,null,null);// 显示全部字段
dynamicFieldColumnDef方法有四个参数,分别是:实体名,列定义数组,显示字段数组,渲染函数。
默认渲染函数:
function render(data, type, row, meta, name){
return row && row.extraProperties && row.extraProperties.dynamicFields && row.extraProperties.dynamicFields[name] ? row.extraProperties.dynamicFields[name] : '';
}
这样在列表 datatable 渲染后就会出现动态属性。 如果不需要在列表中显示动态字段,则不需要5和6步的操作。
7、页面基类
DemoBasePageModel.cs中添加一个同名的泛型类DemoBasePageModel<TEntity>继承自PageModelWithDynamicField<TEntity>。需要引用Hayou.Abp.AspNetCore.Mvc.UI.RazorPages.DynamicField
public abstract class DemoBasePageModel: AbpPageModel
{
protected DynamicFieldDemoPageModel()
{
LocalizationResourceType = typeof(DynamicFieldDemoResource);
}
}
// 添加这个同名的泛型基类
public abstract class DemoBasePageModel<TEntity> : PageModelWithDynamicField<TEntity> where TEntity : Entity<Guid>
{
protected DemoBasePageModel()
{
LocalizationResourceType = typeof(DemoResource);
}
//在这里可以重新定义在详情页显示动态字段的方式,默认是渲染成 html table 的 tr/td。
public override string RenderValue(DynamicFieldValueMiniDto value)
{
return base.RenderValue(value);
}
}
基类中 RenderValue 的默认实现如下,可在重写时自行修改
public string RenderValue(DynamicFieldValueMiniDto value)
{
var valueString = string.Empty;
if (!value.StringValue.IsNullOrWhiteSpace())
{
valueString = value.FieldType switch
{
EnFieldType.Url => $"<a href=\"{value.StringValue}\" target=\"_blank\">{value.StringValue}</a>",
EnFieldType.ImgUrl => $"<img src=\"{value.StringValue}\" class=\"img-thumbnail\" target=\"_blank\" />",
_ => value.StringValue
};
}
return $"\t\t<tr>\r\n\t\t\t<td>{value.DisplayName ?? value.FieldName}</td>\r\n\t\t\t<th>{valueString} </th>\r\n\t\t</tr>";
}
8、在
CreateModal.cshtml.cs和EditModal.cshtml.cs中的基类修改为DemoBasePageModel<Book>, 并在OnPostAsync()方法中提交修改后调用await base.SaveDynamicFieldValues(dto.Id, null, dto.TenantId);保存动态字段的值;
public class CreateModalModel : DemoBasePageModel<Book>
{
public async Task<IActionResult> OnPostAsync()
{
if (ModelState.IsValid)
{
var dto = await _bookPlanAppService.CreateAsync(Book);// or _bookPlanAppService.UpdateAsync(Book) in EditModalModel
//这里保存动态字段值
await base.SaveDynamicFieldValues(dto.Id, null, dto.TenantId);
return Content("");
}
throw new UserFriendlyException("Error");
}
}
9、在
CreateModal.cshtml和EditModal.cshtml中添加 以下代码 显示动态字段的表单:
//新建界面中:
@Html.Raw(await Model.RenderDynamicFieldsAsHtmlFormAsync())
//编辑界面中:
@Html.Raw(await Model.RenderDynamicFieldsAsHtmlFormAsync(Model.Id, null, Model.Book.TenantId))
10、在
DetailModal.cshtml.cs中的基类修改为DemoBasePageModel<Book>:
public class DetailModalModel : DemoBasePageModel<Book>
{
}
11、在
DetailModal.cshtml中添加 以下代码 显示动态字段的表单:
@Html.Raw(await Model.RenderDynamicFieldsAsHtmlTableRowsAsync(Model.Book.ExtraProperties))
如果在第4步的服务层没有填充动态字段值,那就需要直接从服务器获取数据,可使用下面的这个方法:
@Html.Raw(await Model.RenderDynamicFieldsAsHtmlTableRowsAsync(Model.Book.Id))
12、使用Redis缓存
在appsettings.json中可添加缓存配置以使用缓存提升性能
"Redis": {
"IsEnabled": true,
"Configuration": "127.0.0.1:6379,password=[password],defaultdatabase=1,abortConnect=false"
},
版本更新说明:
v0.2.0:
1、升级对.net10.0 和 abp vnext 10.0的支持,移除去 AutoMapper的支持
v0.1.6:
1、优化动态字段表单内容的本地验证和服务端验证
v0.1.5:
1、修复编辑时取不到动态字段值的问题
2、修改了无法取到多选列表框选中的多个值的问题。
v0.1.4:
1、增加链接地址、图片地址、邮箱地址类型的数据支持
2、增加对缓存的处理
3、页面模型基类简化,并能通过重写
RenderValue方法修改详情页的动态字段的显示方式。
v0.1.3:
1、添加对动态值的修改功能,修改时按数据类型提供修改控件
2、增加对多选框和长文本的支持
3、修复布尔类型动态字段在编辑时无法选中的问题。
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Hayou.Abp.DynamicFieldManagement.Domain.Shared (>= 0.2.0)
- Microsoft.EntityFrameworkCore.Abstractions (>= 10.0.0)
- Volo.Abp.Ddd.Domain (>= 10.0.0)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Hayou.Abp.DynamicFieldManagement.Domain:
| Package | Downloads |
|---|---|
|
Hayou.Abp.DynamicFieldManagement.Application
一个基于Abp vNext框架的动态字段模块。 |
|
|
Hayou.Abp.DynamicFieldManagement.EntityFrameworkCore
一个基于Abp vNext框架的动态字段管理模块。 |
GitHub repositories
This package is not used by any popular GitHub repositories.