在 Blazor 中将值从子组件传递到父页面的良好做法?

nog*_*ood 1 events parent-child blazor

我不确定使用我的方法将对象从子组件传递到其在 Blazor 中的消费父页面是否犯了错误。我有一个带有 ID、名称的 poco 类。具有从 poco 类对象列表中选择 div 的组件。用户选择一个条目,该条目应显示在父页面上。我缺乏经验,看不出我的解决方案有任何问题。1)我做对了吗?2)如果一切都好的话,OnInitializedAsync() 没有等待(父级),我应该使用 OnInitialized() 代替吗?3)Dispose的使用是否正确?4)如果我在一个应用程序中针对不同组件等使用相同的方法可能 20 次,那么这个解决方案可以吗?这个规模可以吗?谢谢,不行

父页面:

@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;
    }
}
Run Code Online (Sandbox Code Playgroud)

来自服务的代码(在实际的应用程序中,我使用 MVVM,因此事件代码将位于 ViewModel 中):

    public class MitarbeiterEventService
    {
        public event EventHandler<MitarbeiterLite> EventMitarbeiterChangedInComp;
        public void FireEvent(MitarbeiterLite selMitarbeiterFromComp)
        {
            EventMitarbeiterChangedInComp?.Invoke(this, selMitarbeiterFromComp);
        }
    }
Run Code Online (Sandbox Code Playgroud)

最后是组件本身:

@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 value=@mita.Id>@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));
    }
}
Run Code Online (Sandbox Code Playgroud)

Nei*_*l W 6

与家长沟通时使用EventCallback。当事件的使用者不是父组件或子组件,而是应用程序中与您选择项目的组件没有直接关系的其他组件时,事件服务会更有用。

在你的场景中,我会选择:

成分

    <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 value=@mita.Id>@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

父页面

    @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;
        }
    }
Run Code Online (Sandbox Code Playgroud)