I have a .NET 9 Blazor project that contains a server and a client. In the client project, I have many forms. Those forms have many repetitive sections and some repetitive questions. For example, there is a dropdown list for Channels
(like what you hear about me, and the options are Bing, Google, Friends, and so on).
I want to organize those fields better to avoid redundant code. To simplify, I have a main Razor page:
<EditForm EditContext="_context" OnSubmit="SubmitForm" Enhance><InitialForm Client="@Client" Session="@Session" /></EditForm>@code { Domain.Client? Client; Domain.ClientSession? Session; protected override async Task OnInitializedAsync() { _context = new EditContext(Session); } public void Save() { // Client and Session save }}
The Client
and Session
models are like this:
public class Client { public string? PhobiasNote { get; set; }}public class ClientSession{ public SessionInitial? SessionInitial { get; set; }}public class SessionInitial{ public bool HasPhobias { get; set; } public IList<Phobia>? Phobias { get; set; }}
Then, the InitialForm
is quite a list of inputs. This code is working.
<FormFieldSet><ToggleButtonGroup @bind-Value="@Session.HasPhobias" /><Autocomplete SearchMethod="GetPhobias" @bind-Values="Session.Phobias" EnableDropDown="true" MinimumLength="2" AddItemOnEmptyResultMethod="PhobiaAddedMethod" placeholder="@CommonStrings.SearchPhobias"><SelectedTemplate Context="rl"> @rl.Name</SelectedTemplate><ResultTemplate Context="rl"> @rl.Name</ResultTemplate></Autocomplete><InputTextArea @bind-Value="@Client.PhobiasNote" /><span class="form-field-error"><ValidationMessage For="@(() => Session.Phobias)" /></span></FormFieldSet>@code { [Parameter, EditorRequired] public SessionInitial? Session { get; set; } [Parameter, EditorRequired] public Client? Client { get; set; }}
The logic of the last Razor is to collect info from the user and save it in the Session
or Client
object. When there is a change, I see the change in the main object.
For example, if I want to save the objects, in the function Save
I can see the objects with the new values. I hope it is clear so far.
Now, because the Autocomplete
for this particular kind is quite common, I want to create a Razor component and pass only the field where to save the data. So, the component is called PhobiaSelection
and looks like this
<Autocomplete SearchMethod="GetPhobias" @bind-Values="Phobias" EnableDropDown="true" MinimumLength="2" AddItemOnEmptyResultMethod="PhobiaAddedMethod" placeholder="@CommonStrings.SearchPhobias"><SelectedTemplate Context="rl"> @rl.Name</SelectedTemplate><ResultTemplate Context="rl"> @rl.Name</ResultTemplate></Autocomplete>@code { [Parameter, EditorRequired] public IList<Phobia>? Phobias { get; set; } = default!;}
With this component, the InitialForm
is now more readable and easier
<FormFieldSet><ToggleButtonGroup @bind-Value="@Session.HasPhobias" /><PhobiaSelection Phobias="Session.Phobias" /><InputTextArea @bind-Value="@Client.PhobiasNote" /><span class="form-field-error"><ValidationMessage For="@(() => Session.Phobias)" /></span></FormFieldSet>@code { [Parameter, EditorRequired] public SessionInitial? Session { get; set; } [Parameter, EditorRequired] public Client? Client { get; set; }}
The problem is that in this case if the user selects anything, there are no changes in the variable Session
. I can see that in the PhobiaSelection
the value changes but this is not changing.
Why doesn't the last component (called PhobiaSelection
) update the value in the Session
?