admin管理员组文章数量:1289490
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 anize 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
?
Update
Although I changed the EventCallback
and the OnPhobiasChanged
with both EventCallback<IList<Phobia>>
or EventCallback<IList<Phobia>?>
everywhere, I still get this error.
and this is what I see on ValuesChanged
and this is another try
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 anize 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
?
Update
Although I changed the EventCallback
and the OnPhobiasChanged
with both EventCallback<IList<Phobia>>
or EventCallback<IList<Phobia>?>
everywhere, I still get this error.
and this is what I see on ValuesChanged
and this is another try
Share Improve this question edited Feb 21 at 0:37 Enrico asked Feb 20 at 15:35 EnricoEnrico 6,26611 gold badges78 silver badges176 bronze badges 1- Since you are using multiple custom Razor components, could you create a minimal sample to reproduce the issue so that we can debug and assist you more easily? – Zhi Lv Commented Feb 24 at 8:27
1 Answer
Reset to default 1The problem is probably because you're no longer binding Session.Phobias to the Autoselect values in your PhobiaSelection component.
Change your PhobiaSelection component:
Add:
[Parameter] public EventCallback<IList<Phobia>?> PhobiasChanged { get; set; }
async Task OnPhobiasChanged(IList<Phobia>? changedPhobias)
{
await PhobiasChanged.InvokeAsync(changedPhobias);
}
This makes Phobias in your PhobiaSelection component bindable.
Change
<Autocomplete SearchMethod="GetPhobias"
@bind-Values="Phobias"
...
to
<Autocomplete SearchMethod="GetPhobias"
Values="Phobias"
ValuesChanged="OnPhobiasChanged"
...
This will call OnPhobiasChanged which then raised the EventCallback when something changes, which you'll bind in the parent by changing:
<PhobiaSelection Phobias="Session.Phobias" />
to
<PhobiaSelection @bind-Phobias="Session.Phobias" />
This will then bind the PhobiaSelection selections to Session.Phobias
本文标签: cBlazor with EditForm doesn39t work with componentStack Overflow
版权声明:本文标题:c# - Blazor with EditForm doesn't work with component - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741424824a2378015.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论