简体   繁体   中英

How to pass and bind a selected value from Blazor component to parent

I want to build some reusable input components using Blazor.

Here is my code in the child component:

<div style="width: 100%">
    <div class="create-approval-flow-drop-down">
        <Label Display="Display.Flex">@ChildLabel</Label>      
        <Autocomplete TItem="GraphUser"
                      TValue="string"
                      Data="@users"
                      TextField="@(( item ) => item.DisplayName)"
                      ValueField="@(( item ) => item.DisplayName)"
                      Placeholder="Search..."
                      @bind-SelectedValue="@selectedSearchValue"
                      @bind-SelectedText="@selectedAutoCompleteText">
        </Autocomplete>
    </div>
</div>

@code {

    [Parameter] public string ChildLabel { get; set; }
    [Parameter] public string ChildValue { get; set; }
    [Parameter] public string selectedSearchValue { get; set; }
    [Parameter] public EventCallback<string> ChildLabelChanged { get; set; }
    [Parameter] public EventCallback<string> ChildValueChanged { get; set; }
    [Parameter] public EventCallback<string> selectedSearchValueChanged { get; set; }

    [Inject] public IGraphService GraphService { get; set; }
    public IEnumerable<GraphUser> users = new List<GraphUser>();
    protected override async Task OnInitializedAsync()
    {
        users = await GraphService.GetUsers();
        await base.OnInitializedAsync();
    }

    private Task OnChildValueChanged(ChangeEventArgs e)
    {
        return ChildValueChanged.InvokeAsync(selectedAutoCompleteText);
    }

    string selectedAutoCompleteText { get; set; }   
}

And here is my parent component:

@page "/Test"
@using WireDesk.Web.SubComponents;
@using Blazored.FluentValidation;
@using WireDesk.Models

<WireDesk.Web.SubComponents.SelectAutocomplete.SingleSelectAutoComplete 
ChildLabel="Location Manager"
ChildValue="">
</WireDesk.Web.SubComponents.SelectAutocomplete.SingleSelectAutoComplete>

@ChildLabel;
@ChildValue;

@code 
{
    private string ChildLabel { get; set; }
    private string ChildValue { get; set; }
    public ApprovalFlowForm approvalFlowForm = new ApprovalFlowForm();
}

The child will display the label and create a single select autocomplete text box. The parent will contain a form with a variety of fields, many of which will be a single select autocomplete text box.

I don't want to have to duplicate the code in the child over and over in the parent, but I cannot determine how to pass the string that the user has selected in the child component.

Use an EventCallBack in the child and assign it to a function in the parent. Do something like this. In the parent component:

<ChildComponent TextFieldUpdated="HandleChange" />

And the following code:

private void HandleChange(string value){
    Do stuff...
}

And in the child component:

[Parameter] public EventCallBack<string> TextFieldUpdated {get;set;}

Then all you have to do is this when you want to send the value to the parent component:

TextFieldUpdated.InvokeAsync("String Value");

HandleChange() in the parent component will fire with the value from the child component.

You can do it using EventCallback (like @Joe suggested).

<div style="width: 100%">
    <div class="create-approval-flow-drop-down">
        <Label Display="Display.Flex">@ChildLabel</Label>
        <Autocomplete TItem="GraphUser"
                      TValue="string"
                      Data="@users"
                      TextField="@(( item ) => item.DisplayName)"
                      ValueField="@(( item ) => item.DisplayName)"
                      Placeholder="Search..."
                      SelectedValue="@ChildValue"
                      SelectedValueChanged="OnChildValueChanged">
        </Autocomplete>
    </div>
</div>

@code {
    [Parameter] public string ChildLabel { get; set; }
    [Parameter] public string ChildValue { get; set; }
    [Parameter] public EventCallback<string> ChildValueChanged { get; set; }

    [Inject] public IGraphService GraphService { get; set; }
    public IEnumerable<GraphUser> users = new List<GraphUser>();
    
    protected override async Task OnInitializedAsync()
    {
        users = await GraphService.GetUsers();
        await base.OnInitializedAsync();
    }

    private async Task OnChildValueChanged(string selectedValue)
    {
        ChildValue = selectedValue;
        await ChildValueChanged.InvokeAsync(ChildValue);
    }
}

Usage:

@page "/Test"
@using WireDesk.Web.SubComponents;
@using Blazored.FluentValidation;
@using WireDesk.Models

<WireDesk.Web.SubComponents.SelectAutocomplete.SingleSelectAutoComplete 
    ChildLabel="Location Manager"
    @bind-ChildValue="@childValue">
</WireDesk.Web.SubComponents.SelectAutocomplete.SingleSelectAutoComplete>

@childValue;

@code {
    private string childValue;
    public ApprovalFlowForm approvalFlowForm = new ApprovalFlowForm();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM