Iam uncertain if I'am making a mistake using my approach to pass Objects from a Child Component to its consuming parent page in Blazor. I have a poco class with ID,Name. A component with a select div from a list of poco-class obj.. User selectes a entrie and that entrie shall be shown on the parent page. I am to unexperienct to see any problems with my solution. 1)Did I get it right? 2)If all is kind of okay what is with the OnInitializedAsync() there is no awaiting (Parent) shall I use OnInitialized() instead? 3)Is the use of Dispose correct? 4) Is this solution okay if I use the same approach maybe 20 times in one App for different components etc. Does this scale okay? Thx nogood
ParentPage:
@page "/"
@inject MitarbeiterEventService MitarbeiterEventService
@implements IDisposable
<h1>ParentPage</h1>
<MitarbeiterSel></MitarbeiterSel>
<br />
@if (SelMitarbeiterFromChild != null)
{
<p>Selected Obj. from Child: @SelMitarbeiterFromChild.Name </p>
}
@code{
public MitarbeiterLite SelMitarbeiterFromChild;
protected override async Task OnInitializedAsync()
{
MitarbeiterEventService.EventMitarbeiterChangedInComp += HandelOnMitarbeiterChangedInComp;
}
public async void HandelOnMitarbeiterChangedInComp(object sender, MitarbeiterLite selMitarbeiter)
{
SelMitarbeiterFromChild = selMitarbeiter;
await InvokeAsync(() =>
{
StateHasChanged();
});
}
public void Dispose()
{
MitarbeiterEventService.EventMitarbeiterChangedInComp -= HandelOnMitarbeiterChangedInComp;
}
}
The Code from the service (in the actual App I use MVVM so the event code would be in the ViewModel):
public class MitarbeiterEventService
{
public event EventHandler<MitarbeiterLite> EventMitarbeiterChangedInComp;
public void FireEvent(MitarbeiterLite selMitarbeiterFromComp)
{
EventMitarbeiterChangedInComp?.Invoke(this, selMitarbeiterFromComp);
}
}
And last the component it self:
@inject MitarbeiterEventService MitarbeiterEventService
<h3>MitarbeiterSelection</h3>
<select class="form-control col-6" @onchange="@(x => OnMitarbeiterSelectedChanged(x.Value.ToString()))">
<option value="" disabled selected hidden>--Mitarbeiter--</option>
@foreach (var mita in MitarbeiterLitesLst)
{
<option [email protected]>@mita.Name </option>
}
</select>
@code {
//Ini List
public List<MitarbeiterLite> MitarbeiterLitesLst = new List<MitarbeiterLite>
{
new MitarbeiterLite("Henry"),
new MitarbeiterLite("John"),
new MitarbeiterLite("Sue"),
new MitarbeiterLite("Mary"),
new MitarbeiterLite("Jimmy")
};
public void OnMitarbeiterSelectedChanged(string guidAsString)
{
MitarbeiterEventService.FireEvent(MitarbeiterLitesLst.FirstOrDefault(x => x.Id.ToString() == guidAsString));
}
}
To communicate with the parent use EventCallback
. An Event Service is more useful when the consumer of the event is not a parent or a child, but some other component in your application that does not have a direct relationship with the component where you select the item.
In your scenario, I'd go for:
Component
<h3> MitarbeiterSelection </h3>
<select class="form-control col-6"
@onchange="@(x => OnMitarbeiterSelectedChanged(x.Value.ToString()))">
<option value="" disabled selected hidden> --Mitarbeiter-- </option>
@foreach (var mita in MitarbeiterLitesLst)
{
<option [email protected]>@mita.Name </option>
}
</select>
@code {
[Parameter]
public EventCallback<MitarbeiterLite> OnItemSelected { get; set; }
// Initialize List
public List<MitarbeiterLite> MitarbeiterLitesLst = new List<MitarbeiterLite>
{
new MitarbeiterLite("Henry"),
new MitarbeiterLite("John"),
new MitarbeiterLite("Sue"),
new MitarbeiterLite("Mary"),
new MitarbeiterLite("Jimmy")
};
public void OnMitarbeiterSelectedChanged(string guidAsString)
{
MitarbeiterLite selected =
MitarbeiterLitesLst
.FirstOrDefault(x => x.Id.ToString() == guidAsString);
OnItemSelected.InvokeAsync(selected);
}
}
Parent Page
@page "/"
<h1> ParentPage </h1>
<MitarbeiterSel OnItemSelected=@HandleOnMitarbeiterChangedInComp />
<br />
@if (SelMitarbeiterFromChild != null)
{
<p> Selected Obj. from Child: @SelMitarbeiterFromChild.Name </p>
}
@code{
public MitarbeiterLite SelMitarbeiterFromChild;
public async Task HandelOnMitarbeiterChangedInComp(
MitarbeiterLite selMitarbeiter)
{
SelMitarbeiterFromChild = selMitarbeiter;
}
}