Я хотел бы иметь смесь значков и текстов в параметрах в группе радио, например: Мой код выглядит так:
.rm-input-radio-group {
display: flex;
flex-direction: row;
height: 100px;
}
.rm-input-radio-group img {
margin-left: 10px;
margin-right: 10px;
}
<div class = "rm-input-radio-group">
<EditForm Model = "@rdOptions">
<InputRadioGroup @bind-Value = "@SelectedValue">
@foreach (var option in rdOptions)
{
<InputRadio Value = "@option.Value" /> <img [email protected] /> @option.Text <br />
}
</InputRadioGroup>
</EditForm>
</div>
and the backend code:
[Parameter] public ProposalStatusType SelectedValue { get; set; } = ProposalStatusType.UnderReview;
readonly List<InputRadioGroupItemModel<ProposalStatusType>> rdOptions = new()
{
new InputRadioGroupItemModel<ProposalStatusType>(ProposalStatusType.UnderReview, "Currently being reviewed", "css/svg/icon-in-progress.svg"),
new InputRadioGroupItemModel<ProposalStatusType>(ProposalStatusType.Disliked, "Dislike Proposal Option", "css/svg/icon-thumbdown.svg"),
new InputRadioGroupItemModel<ProposalStatusType>(ProposalStatusType.Preferred, "Preferred Proposal Option", "css/svg/icon-thumbup.svg"),
new InputRadioGroupItemModel<ProposalStatusType>(ProposalStatusType.AvailableForBooking, "Available for Booking Request", "css/svg/icon-bookings.svg"),
};
Однако SelectedValue всегда остается значением по умолчанию/данным при вызове компонента в родительском компоненте. Я ничего не пропустил?
Я думаю, что проблема связана с использованием [параметра] для selectedValue. Родитель перезаписывает значение при его повторном рендеринге.
См. здесь Документация Blazor о перезаписанных параметрах
Используйте локальную переменную, которая получила начальное значение в OnInitialized()
Спасибо Shuryno за подсказку, это правда, и мне пришлось изменить свой код, сначала добавив [Parameter] public EventCallback<OptionStatusType> OnSelectedValueChange { get; set; }
, который может уведомлять родительский компонент об изменениях выбора (что-то вроде: <RMInputRadioGroup SelectedValue = "@SelectedOptionStatus" OnSelectedValueChange = "OnSelectedValueChange" CanApprove = "@CanApprove"></RMInputRadioGroup>
на родительской стороне), а также рефакторинг дочернего html как:
<div class = "rm-input-radio-group">
<EditForm Model = "@RadioGroupItemModel">
<InputRadioGroup Value = "@SelectedValue" ValueChanged = "@((OptionStatusType v) => ValueChanged(v))" ValueExpression = "@( () => RadioGroupItemModel.Value )">
@foreach (var option in rdOptions)
{
<InputRadio Value = "@option.Value" style = "outline: none !important;"/> <img [email protected] /> @option.Text <br />
}
</InputRadioGroup>
</EditForm>
</div>
Вы можете видеть, что я определил более подходящую модель под названием RadioGroupItemModel, например:
protected InputRadioGroupItemModel<OptionStatusType> RadioGroupItemModel { get; set; }
и класс:
public class InputRadioGroupItemModel<T>
{
#region Public Properties
public string Text { get; set; }
public string IconPath { get; set; }
public T Value { get; set; }
#endregion Public Properties
#region Public Constructors
public InputRadioGroupItemModel()
{
}
public InputRadioGroupItemModel(T value, string text, string iconPath)
{
Value = value;
Text = text;
IconPath = iconPath;
}
#endregion Public Constructors
}
а также, как вы можете видеть в коде, мне пришлось заменить @bind-Value = "@SelectedValue"
на Value = "@SelectedValue" ValueChanged = "@((OptionStatusType v) => ValueChanged(v))" ValueExpression = "@( () => RadioGroupItemModel.Value )"
, где
protected void ValueChanged(OptionStatusType value)
{
OnSelectedValueChange.InvokeAsync(value);
}
это работает отлично, но имейте в виду, что вам нужно переопределить стиль на InputRadio (я сделал style = "outline: none !important;"
), поскольку Blazor EditForm автоматически добавит допустимый класс CSS во время выполнения, который добавит рамку вокруг переключателей.