簡體   English   中英

如何使在通用組件中創建的屬性可用於 blazor 中的渲染片段

[英]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 而無需CustomColumsCustomFields標簽

<BasicCatalogCRUD TItem="NormalModel" DataService="@NormalModelService" CrudTitle="Custom Model CRUD"></BasicCatalogCRUD>

有了這個,我終於得到了我的通用 CRUD 和通用表單對話框,可以根據我的需要添加可選的列和字段。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM