im building some blazor app and wanted to make wraper around select so it renders items from some casched dictionary values so i have it like
@typeparam T
@inject DictService _dhttp;
@if (this.Label != null)
{
<MudSelect T="T" @bind-Value="Value" For="@For" Label="@Label" @attributes=AllOtherAttributes>
@if (Nullable.GetUnderlyingType(typeof(T)) != null)
{
<MudSelectItem T="int?" Value="null"> </MudSelectItem>
@foreach (var item in _dict)
{
<MudSelectItem T="int?" Value="item.Key">@item.Value</MudSelectItem>
}
}
else
{
@foreach (var item in _dict)
{
<MudSelectItem T="int" Value="item.Key">@item.Value</MudSelectItem>
}
}
</MudSelect>
}
else
{
<MudSelect T="T" @bind-Value="Value" For="@For" @attributes=AllOtherAttributes>
@if (Nullable.GetUnderlyingType(typeof(T)) != null)
{
<MudSelectItem T="int?" Value="null"> </MudSelectItem>
@foreach (var item in _dict)
{
<MudSelectItem T="int?" Value="item.Key">@item.Value</MudSelectItem>
}
}
else
{
@foreach (var item in _dict)
{
<MudSelectItem T="int" Value="item.Key">@item.Value</MudSelectItem>
}
}
</MudSelect>
}
@code{
[Parameter]
public string? Label {get;set;}
....
}
so can this be simplified ? best would be like
<MudSelect T="T" @bind-Value="Value" For="@For" @if(Label != null){Label="@Label" }@attributes=AllOtherAttributes>
but this not correct for blazor ? (why?)
@if(this.Label != null)
{
<MudSelect T="T" @bind-Value="Value" For="@For" Label="@Label" @attributes=AllOtherAttributes>
}
else
{
<MudSelect T="T" @bind-Value="Value" For="@For" Label="@Label" @attributes=AllOtherAttributes>
}
@if (Nullable.GetUnderlyingType(typeof(T)) != null)
{...
this is also not correct. why it does not allow this ?? requre all tags inside if to be closed. this is some limitation that i was not aware of....
thanks and regards
CodePudding user response:
I believe that this is not correct because you are inside a blazor component and around a parameter. You could think of it as a function. You would not try to put some if statement inside the arguments of a function to specify if the argument is given or not. I don't think components in Blazor are any different for this aspect.
To avoid duplicated code, you can affect the values of your arguments, just like a function:
- put the content of the MudBlazor in a variable or a component.
- try to see if there is any value for Label that would give the same result than not providing the value at all.
CodePudding user response:
Leverage off the @attributes
parameter. But, if implemented correctly, you can pass null
to the Label
parameter, and the component should handle whether it should render or not.
If the component's implementation does not cater for null
, and does something weird, you can add parameters dynamically using the @attributes
parameter.
Example:
<MudSelect T="T" @bind-Value="Value" For="@For" @attributes="AllOtherAttributes">
@code {
protected override void OnParametersSet()
{
AllOtherAttributes = new();
if (AllOtherAttributes.ContainsKey("Label"))
{
if (Label == null)
{
AllOtherAttributes.Remove("Label"); //Remove Label
}
else
{
AllOtherAttributes["Label"] = Label; //Update Label
}
}
else if (Label != null)
{
AllOtherAttributes.Add("Label", Label); //This adds dynamically and works for any Parameter
}
}
EDIT:
Here is another improvement you can make:
<MudSelect T="T" @bind-Value="Value" For="@For" Label="@Label" @attributes=AllOtherAttributes>
@if (Nullable.GetUnderlyingType(typeof(T)) != null)
{
<MudSelectItem T="T" Value="default" />
}
@foreach (var item in _dict)
{
<MudSelectItem T="T" Value="item.Key">@item.Value</MudSelectItem>
}
</MudSelect>
Simplified, and no need to change the Type for T
to int
. This will make this component work for any type.