!735 feat(#I28H8X): Table 组件增加使用数据服务能力

* doc: 增加 UseInjectDataService 文档信息
* doc: 增加数据库连接字符串设置
* doc: 增加利用数据服务示例
* feat: 增加演示数据服务实现类
* doc: 移除表单编辑设置
* refactor: 增加演示示例数据服务注入
* refactor: 修复 PetaPoco 扩展工程错误
* refactor: 增加 UseInjectDataService 参数判断
* build: 移除对 PetaPoco 扩展类依赖
* refactor: 重构 PetaPoco DataService 类
* feat: 增加 DataService 逻辑
* refactor: 设计 IDataService 基类
* feat: 增加 IDataService 注入服务功能
* build: 增加 PetaPoco 数据服务扩展操作类
* doc: 增加 Table 组件使用数据服务示例
* doc: 更新 Tables/Edit Upd 标示
* doc: 增加 DateTimeRange 组件 Upd 标示
* build: 更新依赖到 5.0 版本
This commit is contained in:
Argo 2020-12-07 19:46:09 +08:00
parent ffa47b9541
commit a11e17faa0
18 changed files with 403 additions and 13 deletions

View File

@ -81,6 +81,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BootstrapBlazor.Markdown",
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "extensions", "extensions", "{22328011-53B3-447A-B781-AC3C196B2847}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BootstrapBlazor.DataAcces.PetaPoco", "src\BootstrapBlazor.DataAcces.PetaPoco\BootstrapBlazor.DataAcces.PetaPoco.csproj", "{0D81BCD6-6533-49DA-82A3-0A410B87CF56}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -127,6 +129,10 @@ Global
{B37DA844-38E1-4F39-9562-41F84F3F6C68}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B37DA844-38E1-4F39-9562-41F84F3F6C68}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B37DA844-38E1-4F39-9562-41F84F3F6C68}.Release|Any CPU.Build.0 = Release|Any CPU
{0D81BCD6-6533-49DA-82A3-0A410B87CF56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0D81BCD6-6533-49DA-82A3-0A410B87CF56}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0D81BCD6-6533-49DA-82A3-0A410B87CF56}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0D81BCD6-6533-49DA-82A3-0A410B87CF56}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -147,6 +153,7 @@ Global
{FB6352BD-B93D-4BE4-B8B5-BEC75D81D483} = {22328011-53B3-447A-B781-AC3C196B2847}
{7D8DFDF8-35F7-43A9-8304-1726890B0432} = {22328011-53B3-447A-B781-AC3C196B2847}
{B37DA844-38E1-4F39-9562-41F84F3F6C68} = {22328011-53B3-447A-B781-AC3C196B2847}
{0D81BCD6-6533-49DA-82A3-0A410B87CF56} = {22328011-53B3-447A-B781-AC3C196B2847}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0DCB0756-34FA-4FD0-AE1D-D3F08B5B3A6B}

View File

@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<IsPackable>true</IsPackable>
<PackageIcon>logo.png</PackageIcon>
</PropertyGroup>
<ItemGroup>
<SupportedPlatform Include="browser" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Longbow.PetaPoco" Version="5.0.0" />
<PackageReference Include="PetaPoco.Extensions" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BootstrapBlazor\BootstrapBlazor.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,63 @@
// **********************************
// 框架名称BootstrapBlazor
// 框架作者Argo Zhang
// 开源地址:
// Gitee : https://gitee.com/LongbowEnterprise/BootstrapBlazor
// GitHub: https://github.com/ArgoZhang/BootstrapBlazor
// 开源协议LGPL-3.0 (https://gitee.com/LongbowEnterprise/BootstrapBlazor/blob/dev/LICENSE)
// **********************************
using BootstrapBlazor.Components;
using Microsoft.Extensions.Configuration;
using System.Collections.Generic;
using System.Threading.Tasks;
using PP = PetaPoco;
namespace BootstrapBlazor.DataAcces.PetaPoco
{
/// <summary>
///
/// </summary>
internal class DefaultDataService<TModel> : DataServiceBase<TModel> where TModel : class, new()
{
/// <summary>
///
/// </summary>
public DefaultDataService(IConfiguration config)
{
// 获取连接字符串
}
/// <summary>
///
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public override Task<bool> SaveAsync(TModel model)
{
return base.SaveAsync(model);
}
/// <summary>
///
/// </summary>
/// <param name="option"></param>
/// <returns></returns>
public override Task<QueryData<TModel>> QueryAsync(QueryPageOptions option)
{
return Task.FromResult(new QueryData<TModel>()
{
IsFiltered = true,
IsSearch = true,
IsSorted = true,
TotalCount = 2,
Items = new TModel[]
{
new TModel(),
new TModel()
}
});
}
}
}

View File

@ -0,0 +1,31 @@
// **********************************
// 框架名称BootstrapBlazor
// 框架作者Argo Zhang
// 开源地址:
// Gitee : https://gitee.com/LongbowEnterprise/BootstrapBlazor
// GitHub: https://github.com/ArgoZhang/BootstrapBlazor
// 开源协议LGPL-3.0 (https://gitee.com/LongbowEnterprise/BootstrapBlazor/blob/dev/LICENSE)
// **********************************
using BootstrapBlazor.Components;
using BootstrapBlazor.DataAcces.PetaPoco;
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// BootstrapBlazor 服务扩展类
/// </summary>
public static class PetaPocoServiceCollectionExtensions
{
/// <summary>
/// 增加 PetaPoco 数据库操作服务
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public static IServiceCollection AddPetaPoco(this IServiceCollection services)
{
services.AddSingleton(typeof(IDataService<>), typeof(DefaultDataService<>));
return services;
}
}
}

View File

@ -0,0 +1,28 @@
<Table TItem="BindItem"
IsPagination="true" PageItemsSource="@PageItemsSource"
IsStriped="true" IsBordered="true" IsMultipleSelect="true"
ShowToolbar="true" ShowExtendButtons="true" ShowSkeleton="true" UseInjectDataService="true">
<TableColumns>
<TableColumn @bind-Field="@context.DateTime" Width="180" />
<TableColumn @bind-Field="@context.Name">
<EditTemplate Context="value">
<div class="form-group col-12 col-sm-6">
<TablesNameDrop Model="@((BindItem)value)" />
</div>
</EditTemplate>
</TableColumn>
<TableColumn @bind-Field="@context.Address" />
<TableColumn @bind-Field="@context.Education" />
<TableColumn @bind-Field="@context.Count" />
<TableColumn @bind-Field="@context.Complete">
<Template Context="v">
<Switch IsDisabled="true" Value="v.Value" ShowInnerText="true" OnInnerText="是" OffInnerText="否" />
</Template>
<EditTemplate Context="v">
<div class="form-group col-12 col-sm-6">
<Switch @bind-Value="(v as BindItem)!.Complete" ShowInnerText="true" OnInnerText="是" OffInnerText="否" />
</div>
</EditTemplate>
</TableColumn>
</TableColumns>
</Table>

View File

@ -71,6 +71,9 @@ namespace BootstrapBlazor.Server
// 增加 Table Excel 导出服务
services.AddBootstrapBlazorTableExcelExport();
// 增加 Table 数据服务操作类
services.AddTableDemoDataService();
// 统一设置 Toast 组件自动消失时间
services.Configure<BootstrapBlazorOptions>(options =>
{

View File

@ -7,6 +7,9 @@
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"ba": "Data Source=bb.db;"
},
"SupportCultures": [
"en-US",
"de-DE",

View File

@ -16,9 +16,9 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="BootstrapBlazor.Chart" Version="3.1.1" />
<PackageReference Include="BootstrapBlazor.Markdown" Version="3.1.1" />
<PackageReference Include="BootstrapBlazor.TableExport" Version="3.1.1" />
<PackageReference Include="BootstrapBlazor.Chart" Version="5.0.0" />
<PackageReference Include="BootstrapBlazor.Markdown" Version="5.0.0" />
<PackageReference Include="BootstrapBlazor.TableExport" Version="5.0.0" />
<PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
</ItemGroup>

View File

@ -0,0 +1,62 @@
// **********************************
// 框架名称BootstrapBlazor
// 框架作者Argo Zhang
// 开源地址:
// Gitee : https://gitee.com/LongbowEnterprise/BootstrapBlazor
// GitHub: https://github.com/ArgoZhang/BootstrapBlazor
// 开源协议LGPL-3.0 (https://gitee.com/LongbowEnterprise/BootstrapBlazor/blob/dev/LICENSE)
// **********************************
using BootstrapBlazor.Components;
using BootstrapBlazor.Shared.Pages;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// BootstrapBlazor 服务扩展类
/// </summary>
public static class TableDemoDataServiceCollectionExtensions
{
/// <summary>
/// 增加 PetaPoco 数据库操作服务
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public static IServiceCollection AddTableDemoDataService(this IServiceCollection services)
{
services.AddSingleton(typeof(IDataService<>), typeof(TableDemoDataService<>));
return services;
}
}
/// <summary>
/// 演示网站示例数据注入服务实现类
/// </summary>
internal class TableDemoDataService<TModel> : DataServiceBase<TModel> where TModel : class, new()
{
/// <summary>
/// 查询操作方法
/// </summary>
/// <param name="options"></param>
/// <returns></returns>
public override Task<QueryData<TModel>> QueryAsync(QueryPageOptions options)
{
// 此处代码实战中不可用,仅仅为演示而写
var items = TablesBase.GenerateItems().Cast<TModel>();
var total = items.Count();
// 内存分页
items = items.Skip((options.PageIndex - 1) * options.PageItems).Take(options.PageItems).ToList();
return Task.FromResult(new QueryData<TModel>()
{
Items = items,
TotalCount = total
});
}
}
}

View File

@ -38,7 +38,7 @@ namespace BootstrapBlazor.Shared.Pages
///
/// </summary>
/// <returns></returns>
protected static List<BindItem> GenerateItems() => Enumerable.Range(1, 80).Select(i => new BindItem()
internal static List<BindItem> GenerateItems() => Enumerable.Range(1, 80).Select(i => new BindItem()
{
Id = i,
Name = $"张三 {i:d4}",

View File

@ -162,3 +162,45 @@
</TableColumns>
</Table>
</Block>
<Block Title="使用注入数据服务" Introduction="通过设置表格的 <code>UseInjectDataService</code> 属性,使用数据服务进行对数据的增删改查" CodeFile="table.58.html">
<p>
通过 <code>UseInjectDataService="true"</code> 开启使用数据服务进行增、删、改、查的数据库操作,而无需对以下回调委托进行赋值,优先级别为有回调方法优先调用回调方法,如无则调用注入服务进行数据操作
<ul class="ul-demo">
<li><code>OnAddAsync</code></li>
<li><code>OnDeleteAsync</code></li>
<li><code>OnSaveAsync</code></li>
<li><code>OnQueryAsync</code></li>
</ul>
<div>Startup 文件注入数据服务 <a href="https://gitee.com/LongbowEnterprise/BootstrapBlazor/wikis/Table%20%E7%BB%84%E4%BB%B6%E6%95%B0%E6%8D%AE%E6%9C%8D%E5%8A%A1%E4%BB%8B%E7%BB%8D?sort_id=3207977" target="_blank">实现原理与用法介绍</a></div>
</p>
<Pre class="no-highlight mt-3">services.AddTableDemoDataService();</Pre>
<Table TItem="BindItem"
IsPagination="true" PageItemsSource="@PageItemsSource"
IsStriped="true" IsBordered="true" IsMultipleSelect="true"
ShowToolbar="true" ShowExtendButtons="true" ShowSkeleton="true" UseInjectDataService="true">
<TableColumns>
<TableColumn @bind-Field="@context.DateTime" Width="180" />
<TableColumn @bind-Field="@context.Name">
<EditTemplate Context="value">
<div class="form-group col-12 col-sm-6">
<TablesNameDrop Model="@((BindItem)value)" />
</div>
</EditTemplate>
</TableColumn>
<TableColumn @bind-Field="@context.Address" />
<TableColumn @bind-Field="@context.Education" />
<TableColumn @bind-Field="@context.Count" />
<TableColumn @bind-Field="@context.Complete">
<Template Context="v">
<Switch IsDisabled="true" Value="v.Value" ShowInnerText="true" OnInnerText="是" OffInnerText="否" />
</Template>
<EditTemplate Context="v">
<div class="form-group col-12 col-sm-6">
<Switch @bind-Value="(v as BindItem)!.Complete" ShowInnerText="true" OnInnerText="是" OffInnerText="否" />
</div>
</EditTemplate>
</TableColumn>
</TableColumns>
</Table>
</Block>

View File

@ -189,7 +189,8 @@ namespace BootstrapBlazor.Shared.Shared
item.AddItem(new DemoMenuItem()
{
Text = "时间范围框 DateTimeRange",
Url = "datetimeranges"
Url = "datetimeranges",
IsUpdate = true
});
item.AddItem(new DemoMenuItem()
{
@ -455,7 +456,8 @@ namespace BootstrapBlazor.Shared.Shared
it.AddItem(new DemoMenuItem()
{
Text = "表单维护",
Url = "tables/edit"
Url = "tables/edit",
IsUpdate = true
});
it.AddItem(new DemoMenuItem()

View File

@ -0,0 +1,48 @@
// **********************************
// 框架名称BootstrapBlazor
// 框架作者Argo Zhang
// 开源地址:
// Gitee : https://gitee.com/LongbowEnterprise/BootstrapBlazor
// GitHub: https://github.com/ArgoZhang/BootstrapBlazor
// 开源协议LGPL-3.0 (https://gitee.com/LongbowEnterprise/BootstrapBlazor/blob/dev/LICENSE)
// **********************************
using System.Collections.Generic;
using System.Threading.Tasks;
namespace BootstrapBlazor.Components
{
/// <summary>
/// IDataServie 实现类基类
/// </summary>
public abstract class DataServiceBase<TModel> : IDataService<TModel> where TModel : class, new()
{
/// <summary>
/// 新建实体类配置方法
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public virtual Task Config(in TModel model) => Task.CompletedTask;
/// <summary>
/// 删除数据操作方法
/// </summary>
/// <param name="models"></param>
/// <returns></returns>
public virtual Task<bool> DeleteAsync(IEnumerable<TModel> models) => Task.FromResult(true);
/// <summary>
/// 保存数据操作方法
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public virtual Task<bool> SaveAsync(TModel model) => Task.FromResult(true);
/// <summary>
/// 查询数据操作方法
/// </summary>
/// <param name="option"></param>
/// <returns></returns>
public abstract Task<QueryData<TModel>> QueryAsync(QueryPageOptions option);
}
}

View File

@ -0,0 +1,47 @@
// **********************************
// 框架名称BootstrapBlazor
// 框架作者Argo Zhang
// 开源地址:
// Gitee : https://gitee.com/LongbowEnterprise/BootstrapBlazor
// GitHub: https://github.com/ArgoZhang/BootstrapBlazor
// 开源协议LGPL-3.0 (https://gitee.com/LongbowEnterprise/BootstrapBlazor/blob/dev/LICENSE)
// **********************************
using System.Collections.Generic;
using System.Threading.Tasks;
namespace BootstrapBlazor.Components
{
/// <summary>
/// IDataService 接口
/// </summary>
public interface IDataService<TModel> where TModel : class, new()
{
/// <summary>
/// 创建新数据实体类回调方法
/// </summary>
/// <returns></returns>
Task Config(in TModel model);
/// <summary>
/// 删除数据方法
/// </summary>
/// <param name="models">要删除的数据集合</param>
/// <returns>成功返回真,失败返回假</returns>
Task<bool> DeleteAsync(IEnumerable<TModel> models);
/// <summary>
/// 保存数据方法
/// </summary>
/// <param name="model">保存实体类实例</param>
/// <returns></returns>
Task<bool> SaveAsync(TModel model);
/// <summary>
/// 查询数据方法
/// </summary>
/// <param name="option">查询条件参数集合</param>
/// <returns></returns>
Task<QueryData<TModel>> QueryAsync(QueryPageOptions option);
}
}

View File

@ -503,7 +503,7 @@ RenderFragment<TItem> RenderEditForm => item =>
}
else
{
<ValidateForm Model="@item" OnValidSubmit="@(new Func<EditContext, Task>(Save))">
<ValidateForm Model="@item" OnValidSubmit="@(new Func<EditContext, Task>(SaveAsync))">
<CascadingValue Value="Columns" IsFixed="true">
<EditorForm TModel="TItem">
<Buttons>

View File

@ -175,6 +175,12 @@ namespace BootstrapBlazor.Components
[Parameter]
public bool AutoGenerateColumns { get; set; }
/// <summary>
/// 获得/设置 注入数据服务
/// </summary>
[Inject]
public IDataService<TItem>? DataService { get; set; }
/// <summary>
/// 单选模式下选择行时调用此方法
/// </summary>
@ -237,6 +243,19 @@ namespace BootstrapBlazor.Components
SearchModel = SearchModel
});
}
else if (UseInjectDataService && DataService != null)
{
queryData = await DataService.QueryAsync(new QueryPageOptions()
{
PageIndex = PageIndex,
PageItems = PageItems,
SearchText = SearchText,
SortOrder = SortOrder,
SortName = SortName,
Filters = Filters.Values,
SearchModel = SearchModel
});
}
if (queryData != null)
{
Items = queryData.Items;

View File

@ -179,9 +179,14 @@ namespace BootstrapBlazor.Components
/// </summary>
public async Task AddAsync()
{
if (OnSaveAsync != null)
if ((UseInjectDataService && DataService != null) || OnSaveAsync != null)
{
if (OnAddAsync != null) EditModel = await OnAddAsync();
else if (DataService != null)
{
EditModel = new TItem();
await DataService.Config(EditModel);
}
else EditModel = new TItem();
SelectedItems.Clear();
@ -217,7 +222,7 @@ namespace BootstrapBlazor.Components
/// </summary>
public Task EditAsync()
{
if (OnSaveAsync != null)
if ((UseInjectDataService && DataService != null) || OnSaveAsync != null)
{
if (SelectedItems.Count == 1)
{
@ -275,10 +280,10 @@ namespace BootstrapBlazor.Components
/// 保存数据
/// </summary>
/// <param name="context"></param>
protected async Task Save(EditContext context)
protected async Task SaveAsync(EditContext context)
{
var valid = false;
if (OnSaveAsync != null)
if (DataService != null || OnSaveAsync != null)
{
if (EditMode == EditMode.EditForm)
{
@ -286,7 +291,8 @@ namespace BootstrapBlazor.Components
ShowEditForm = false;
}
valid = await OnSaveAsync((TItem)context.Model);
if (OnSaveAsync != null) valid = await OnSaveAsync((TItem)context.Model);
else if (DataService != null) valid = await DataService.SaveAsync((TItem)context.Model);
var option = new ToastOption
{
Category = valid ? ToastCategory.Success : ToastCategory.Error,
@ -328,7 +334,7 @@ namespace BootstrapBlazor.Components
{
new KeyValuePair<string, object>(nameof(TableEditorDialog<TItem>.Model), EditModel),
new KeyValuePair<string, object>(nameof(TableEditorDialog<TItem>.Columns), Columns.Where(i => i.Editable)),
new KeyValuePair<string, object>(nameof(TableEditorDialog<TItem>.OnSaveAsync), new Func<EditContext, Task>(Save)),
new KeyValuePair<string, object>(nameof(TableEditorDialog<TItem>.OnSaveAsync), new Func<EditContext, Task>(SaveAsync)),
new KeyValuePair<string, object>(nameof(TableEditorDialog<TItem>.ShowLabel), false),
new KeyValuePair<string, object>(nameof(TableEditorDialog<TItem>.BodyTemplate), EditTemplate!)
};
@ -368,6 +374,7 @@ namespace BootstrapBlazor.Components
{
var ret = false;
if (OnDeleteAsync != null) ret = await OnDeleteAsync(SelectedItems);
else if (UseInjectDataService && DataService != null) ret = await DataService.DeleteAsync(SelectedItems);
var option = new ToastOption()
{
Title = DeleteButtonToastTitle

View File

@ -125,6 +125,12 @@ namespace BootstrapBlazor.Components
/// </summary>
public List<ITableColumn> Columns { get; } = new List<ITableColumn>(50);
/// <summary>
/// 获得/设置 是否使用注入的数据服务
/// </summary>
[Parameter]
public bool UseInjectDataService { get; set; }
/// <summary>
/// 获得/设置 明细行模板
/// </summary>