[英]How to make a property created in a generic Component available to the Render Fragment in blazor
如何使在通用组件中创建的属性可用于渲染片段内容的定义
我是 blazor 的新手,并尝试基于如下所示的 model 制作通用 CRUD 组件。 我的许多其他类都继承自这个 model 并且不添加任何字段
public class BasicCatalogModel
{
[Key]
public virtual long Id { get; set; }
public virtual String Name { get; set; }
public virtual String Description { get; set; }
public virtual bool Enabled { get; set; }
}
然后我有一个具有如下签名的通用数据服务:
public class BasicCatalogService<T>: ICatalogService<T> where T: BasicCatalogModel
该服务被注入到在我的 CustomModelCRUD 中创建的“通用”组件中。 我需要做的是为那些需要添加一两个额外字段的模型添加自定义列和自定义字段
<BasicCatalogCRUD TItem="CustomModel" DataService="@CustomService" CrudTitle="@modelLocalizer["Custom.crud.title"]">
<CustomColumns>
<div>HERE are my custom columns and this works since I don´t need to add a reference to the current item</div>
</CustomColumns>
<CustomFields>
I need to add a custom field where I use the currentItem created in BasicCatalogCRUD
I need to make the field visible here to add a custom Field to the form
<input value="currentItem.CustomField">
<CustomFields>
</BasicCatalogCRUD>
这是通用 CRUD 的一部分,因为它现在是
@inject IStringLocalizer<ModelResource> modelLocalizer
@inject NotificationService NotificationService
@inject DialogService DialogService
@typeparam TItem
<h1>@CrudTitle</h1>
<Columns>
//Columns Before
@CustomColumns
//Colums After
</Columns>
</div>
@code {
/// <summary>
/// The item I need to access in the RenderFragment CustomFields
/// </summary>
TItem currentItem;
[Parameter] public BasicCatalogoService<TItem> DataService { get; set; }
[Parameter] public String CrudTitle { get; set; }
[Parameter] public RenderFragment CustomColumns { get; set; }
///I also need to pass the CustomFields value to the Dialog
[Parameter] public RenderFragment CustomFields { get; set; }
/// <summary>
/// Here we load the generic Form on to a RadzedDialog
/// </summary>
void LoadDataOnForm(TItem objectInstance)
{
currentItem = objectInstance;
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("CurrentItem", objectInstance);
parameters.Add("FieldTitle", GetActionLabel());
parameters.Add("ItemGrid", itemGrid);
parameters.Add("LabelBuilder", labelBuilder);
parameters.Add("DataService", DataService);
//I add the parameter to the parameters and send it to the dialog.
parameters.Add("CustomFields", CustomFields);
DialogOptions dialogOptions = new DialogOptions() { Width = "700px", Height = "600px" };
DialogService.Open<BasicCatalogoForm<TItem>>(GetActionLabel(), parameters, dialogOptions);
}
}
最后是表格的代码
@inject IStringLocalizer<ModelResource> modelLocalizer
@inject IStringLocalizer<AppResource> appLocalizer
@inject NotificationService NotificationService
@inject DialogService DialogService
@typeparam TItem
@if (CurrentItem != null)
{
<RadzenTemplateForm TItem="TItem" Data="@CurrentItem" Submit=@OnSubmit InvalidSubmit=@OnInvalidSubmit>
<FluentValidationValidator />
<RadzenFieldset>
//Fields Before ...
//The fields should be inserted here
@CustomFields
</RadzenFieldset>
<RadzenButton ButtonType="ButtonType.Submit" Icon="save" Text="@appLocalizer["button.save.label"]" />
</RadzenTemplateForm>
}
@code {
[Parameter] public String FieldTitle { get; set; }
[Parameter] public TItem CurrentItem { get; set; }
[Parameter] public BasicCatalogoService<TItem> DataService { get; set; }
[Parameter] public RenderFragment CustomFields { get; set; }
}
我目前正在研究将数据传递给渲染片段(据我所知,这似乎不能解决我的问题)和级联值(似乎也不是正确的选择)。 那么,如何使 currentItem 在 CustomModelCRUD 中可用?
所以,我实际上是非常错误的,你可以使用 RenderFragments 来完成这个。
首先,需要将渲染片段添加到通用表单中。 查找HERE:评论以查看其添加位置。 通过这样做,我们可以将 TItem 类型的值传递给渲染片段
@typeparam TItem
@if (CurrentItem != null)
{
<RadzenTemplateForm TItem="TItem" Data="@CurrentItem" Submit=@OnSubmit InvalidSubmit=@OnInvalidSubmit>
<FluentValidationValidator />
<RadzenFieldset>
//Fields Before ...
//HERE : The fields should be inserted here but we need to check if
//we are receiving the fragment and if the currentItem is set.
//Adding the nullchecks also allows us to make the customFields an
//optional thing
@if (CustomFields != null && CurrentItem != null)
{
@CustomFields(CurrentItem)
}
//... Fields After
</RadzenFieldset>
<RadzenButton ButtonType="ButtonType.Submit" Icon="save" Text="@appLocalizer["button.save.label"]" />
</RadzenTemplateForm>
}
@code {
[Parameter] public String FieldTitle { get; set; }
[Parameter] public TItem CurrentItem { get; set; }
[Parameter] public BasicCatalogoService<TItem> DataService { get; set; }
[Parameter] public RenderFragment<TItem> CustomFields { get; set; } //HERE: This is how I added the render fragment
}
之后,我们需要将片段添加到通用 CRUD。 再次寻找这里:评论。
@inject IStringLocalizer<ModelResource> modelLocalizer
@inject NotificationService NotificationService
@inject DialogService DialogService
@typeparam TItem
<h1>@CrudTitle</h1>
<Columns>
//Columns Before
//HERE: We also need to to a null check for the custom
//columns to make them optional
@if (CustomColumns != null)
{
@CustomColumns
}
//Colums After
</Columns>
</div>
@code {
/// <summary>
/// The item I need to access in the RenderFragment CustomFields
/// </summary>
TItem currentItem;
[Parameter] public BasicCatalogoService<TItem> DataService { get; set; }
[Parameter] public String CrudTitle { get; set; }
//HERE: the custom colums stay as they are.
[Parameter] public RenderFragment CustomColumns { get; set; }
//HERE: We add the RenderFragment. The fragment MUST have the same signature
//as the one in the Generic Form above
[Parameter] public RenderFragment<TItem> CustomFields { get; set; }
/// <summary>
/// Here we load the generic Form on to a RadzedDialog
/// </summary>
void LoadDataOnForm(TItem objectInstance)
{
currentItem = objectInstance;
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("CurrentItem", objectInstance);
parameters.Add("FieldTitle", GetActionLabel());
parameters.Add("ItemGrid", itemGrid);
parameters.Add("LabelBuilder", labelBuilder);
parameters.Add("DataService", DataService);
//HERE: The super important part. it is necessary to do a null check, and pass the CustomFields to the
//generic form. DO NOT do it like this: parameters.Add("CustomFields", CustomFields(CurrentItem));
if (CustomFields != null)
{
parameters.Add("CustomFields", CustomFields);
}
DialogOptions dialogOptions = new DialogOptions() { Width = "700px", Height = "600px" };
DialogService.Open<BasicCatalogoForm<TItem>>(GetActionLabel(), parameters, dialogOptions);
}
}
最后我们需要在 CustomModelCRUD 中声明片段
<BasicCatalogCRUD TItem="CustomModel" DataService="@CustomModelService" CrudTitle="Custom Model CRUD">
@*HERE: this is optional and the models that follow the BasicCatalogModel don´t need to add this.*@
<CustomColumns>
<RadzenGridColumn TItem="CustomModel" Property="CustomProperty" Title="Custom Property" />
</CustomColumns>
@*HERE: this is optional and the models that follow the BasicCatalogModel don´t need to add this.*@
<CustomFields>
@*HERE: we can access the value of the CurrentItem in the BasicCatalogCRUD using the context keyword*@
@*but we must Make a NullCheck because when the BasicCatalogCRUD is initialized there might be no*@
@*current Item set and a nullPointer Exception could be thrown. *@
@if (context != null)
{
<div class="row">
<div class="col-md-4 align-items-center">
<RadzenLabel Text="@modelLocalizer["prioridad.field.CustomProperty.label"]" />
</div>
<div class="col-md-8">
<RadzenNumeric TValue="int" Min="1" Max="100" @bind-Value="context.CustomProperty" />
<span class="field-error-message"><ValidationMessage For="@(() => context.CustomProperty)" /></span>
</div>
</div>
}
</CustomFields>
</BasicCatalogCRUD>
由于 CRUD 和 DialogForm 是通用的,我们还可以创建其他 CRUD 而无需CustomColums
和CustomFields
标签
<BasicCatalogCRUD TItem="NormalModel" DataService="@NormalModelService" CrudTitle="Custom Model CRUD"></BasicCatalogCRUD>
有了这个,我终于得到了我的通用 CRUD 和通用表单对话框,可以根据我的需要添加可选的列和字段。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.