简体   繁体   中英

How to get two-way binding in Blazor with a SELECT Component?

I am trying to write a Blazor component that uses a <select...> , to update the variable passed in from the parent.

I want to click on the drop-down (select/options), choose an option, and have that automatically update the variable in the parent.

I can get it to work if I don't use a component. But the only way I can get it to work from a component is if I also use a button in the component (see the button in the Component code). But eventually there will be several components called from the same parent. It would not be practical to have a separate button for each component. So the button has to go away.

The @bind uses the "onchange" parameter to the select, so that won't even compile.

I've tried CascadingValue/CascadingParam but that does not update the parent value either (unless I use a button...)

Here is the parent:

@page "/test"
@page "/test/{param}"

@namespace ComponentTest.Pages

@using System.Web
@using ComponentTest.Pages

<h3>Test Page</h3>

<div class="border col-3">
    <h4>Parent</h4>
    <hr />
    <label for="parentValue">Parent Value</label>
    <input id="parentValue" @bind="@param"/>
</div>
<div class="col-3">&nbsp</div>
<div class="border col-3">
    <h4>Component Select</h4>
    <hr />
    <SelectComponent @bind-Item="@param"/>
</div>

@code {
    [Parameter]
    public string param { get; set; }
}

And here is the component:

@using System.Collections.Generic
@using System.Web

<div class="form-group">
    <p>Component Value = @Item</p>
    <label for="Site" class="font-weight-bold form-check-label">List</label>
    @if (list == null)
    {
        <input id="Item" class="form-control-sm" @bind="@Item" />
    }
    else
    {
        <select id="Item" class="form-control-sm" @bind="@Item">
            @foreach (var l in list)
            {
                @if (Item != null && String.Equals(l, Item, StringComparison.OrdinalIgnoreCase))
                {
                    <option selected value="@l">@l</option>
                }
                else
                {
                    <option value="@l">@l</option>
                }
            }
        </select>
    }
</div>
<button @onclick="UpdateParentsItem" class="btn btn-primary">Update Parent</button>
@code {
    public IEnumerable<string> list = new List<string>()
{
        "Item 1",
        "Item 2",
        "Item 3",
        "Item 4",
        "Item 5"
    };

    [Parameter]
    public string Item { get; set; }

    [Parameter]
    public EventCallback<string> ItemChanged { get; set; }

    private async Task UpdateParentsItem()
    {
        await ItemChanged.InvokeAsync(Item);
    }
}

I followed a few groovy examples for implementing events but none that I found actually solved the problem.

I have searched SO and there are several questions and answers on this subject but none solve this specific problem.

I am trying to write a Blazor component that uses a <select...> , to update the variable passed in from the parent.

I want to click on the drop-down (select/options), choose an option, and have that automatically update the variable in the parent.

I can get it to work if I don't use a component. But the only way I can get it to work from a component is if I also use a button in the component (see the button in the Component code). But eventually there will be several components called from the same parent. It would not be practical to have a separate button for each component. So the button has to go away.

The @bind uses the "onchange" parameter to the select, so that won't even compile.

I've tried CascadingValue/CascadingParam but that does not update the parent value either (unless I use a button...)

Here is the parent:

@page "/test"
@page "/test/{param}"

@namespace ComponentTest.Pages

@using System.Web
@using ComponentTest.Pages

<h3>Test Page</h3>

<div class="border col-3">
    <h4>Parent</h4>
    <hr />
    <label for="parentValue">Parent Value</label>
    <input id="parentValue" @bind="@param"/>
</div>
<div class="col-3">&nbsp</div>
<div class="border col-3">
    <h4>Component Select</h4>
    <hr />
    <SelectComponent @bind-Item="@param"/>
</div>

@code {
    [Parameter]
    public string param { get; set; }
}

And here is the component:

@using System.Collections.Generic
@using System.Web

<div class="form-group">
    <p>Component Value = @Item</p>
    <label for="Site" class="font-weight-bold form-check-label">List</label>
    @if (list == null)
    {
        <input id="Item" class="form-control-sm" @bind="@Item" />
    }
    else
    {
        <select id="Item" class="form-control-sm" @bind="@Item">
            @foreach (var l in list)
            {
                @if (Item != null && String.Equals(l, Item, StringComparison.OrdinalIgnoreCase))
                {
                    <option selected value="@l">@l</option>
                }
                else
                {
                    <option value="@l">@l</option>
                }
            }
        </select>
    }
</div>
<button @onclick="UpdateParentsItem" class="btn btn-primary">Update Parent</button>
@code {
    public IEnumerable<string> list = new List<string>()
{
        "Item 1",
        "Item 2",
        "Item 3",
        "Item 4",
        "Item 5"
    };

    [Parameter]
    public string Item { get; set; }

    [Parameter]
    public EventCallback<string> ItemChanged { get; set; }

    private async Task UpdateParentsItem()
    {
        await ItemChanged.InvokeAsync(Item);
    }
}

I followed a few groovy examples for implementing events but none that I found actually solved the problem.

I have searched SO and there are several questions and answers on this subject but none solve this specific problem.

I am trying to write a Blazor component that uses a <select...> , to update the variable passed in from the parent.

I want to click on the drop-down (select/options), choose an option, and have that automatically update the variable in the parent.

I can get it to work if I don't use a component. But the only way I can get it to work from a component is if I also use a button in the component (see the button in the Component code). But eventually there will be several components called from the same parent. It would not be practical to have a separate button for each component. So the button has to go away.

The @bind uses the "onchange" parameter to the select, so that won't even compile.

I've tried CascadingValue/CascadingParam but that does not update the parent value either (unless I use a button...)

Here is the parent:

@page "/test"
@page "/test/{param}"

@namespace ComponentTest.Pages

@using System.Web
@using ComponentTest.Pages

<h3>Test Page</h3>

<div class="border col-3">
    <h4>Parent</h4>
    <hr />
    <label for="parentValue">Parent Value</label>
    <input id="parentValue" @bind="@param"/>
</div>
<div class="col-3">&nbsp</div>
<div class="border col-3">
    <h4>Component Select</h4>
    <hr />
    <SelectComponent @bind-Item="@param"/>
</div>

@code {
    [Parameter]
    public string param { get; set; }
}

And here is the component:

@using System.Collections.Generic
@using System.Web

<div class="form-group">
    <p>Component Value = @Item</p>
    <label for="Site" class="font-weight-bold form-check-label">List</label>
    @if (list == null)
    {
        <input id="Item" class="form-control-sm" @bind="@Item" />
    }
    else
    {
        <select id="Item" class="form-control-sm" @bind="@Item">
            @foreach (var l in list)
            {
                @if (Item != null && String.Equals(l, Item, StringComparison.OrdinalIgnoreCase))
                {
                    <option selected value="@l">@l</option>
                }
                else
                {
                    <option value="@l">@l</option>
                }
            }
        </select>
    }
</div>
<button @onclick="UpdateParentsItem" class="btn btn-primary">Update Parent</button>
@code {
    public IEnumerable<string> list = new List<string>()
{
        "Item 1",
        "Item 2",
        "Item 3",
        "Item 4",
        "Item 5"
    };

    [Parameter]
    public string Item { get; set; }

    [Parameter]
    public EventCallback<string> ItemChanged { get; set; }

    private async Task UpdateParentsItem()
    {
        await ItemChanged.InvokeAsync(Item);
    }
}

I followed a few groovy examples for implementing events but none that I found actually solved the problem.

I have searched SO and there are several questions and answers on this subject but none solve this specific problem.

I am trying to write a Blazor component that uses a <select...> , to update the variable passed in from the parent.

I want to click on the drop-down (select/options), choose an option, and have that automatically update the variable in the parent.

I can get it to work if I don't use a component. But the only way I can get it to work from a component is if I also use a button in the component (see the button in the Component code). But eventually there will be several components called from the same parent. It would not be practical to have a separate button for each component. So the button has to go away.

The @bind uses the "onchange" parameter to the select, so that won't even compile.

I've tried CascadingValue/CascadingParam but that does not update the parent value either (unless I use a button...)

Here is the parent:

@page "/test"
@page "/test/{param}"

@namespace ComponentTest.Pages

@using System.Web
@using ComponentTest.Pages

<h3>Test Page</h3>

<div class="border col-3">
    <h4>Parent</h4>
    <hr />
    <label for="parentValue">Parent Value</label>
    <input id="parentValue" @bind="@param"/>
</div>
<div class="col-3">&nbsp</div>
<div class="border col-3">
    <h4>Component Select</h4>
    <hr />
    <SelectComponent @bind-Item="@param"/>
</div>

@code {
    [Parameter]
    public string param { get; set; }
}

And here is the component:

@using System.Collections.Generic
@using System.Web

<div class="form-group">
    <p>Component Value = @Item</p>
    <label for="Site" class="font-weight-bold form-check-label">List</label>
    @if (list == null)
    {
        <input id="Item" class="form-control-sm" @bind="@Item" />
    }
    else
    {
        <select id="Item" class="form-control-sm" @bind="@Item">
            @foreach (var l in list)
            {
                @if (Item != null && String.Equals(l, Item, StringComparison.OrdinalIgnoreCase))
                {
                    <option selected value="@l">@l</option>
                }
                else
                {
                    <option value="@l">@l</option>
                }
            }
        </select>
    }
</div>
<button @onclick="UpdateParentsItem" class="btn btn-primary">Update Parent</button>
@code {
    public IEnumerable<string> list = new List<string>()
{
        "Item 1",
        "Item 2",
        "Item 3",
        "Item 4",
        "Item 5"
    };

    [Parameter]
    public string Item { get; set; }

    [Parameter]
    public EventCallback<string> ItemChanged { get; set; }

    private async Task UpdateParentsItem()
    {
        await ItemChanged.InvokeAsync(Item);
    }
}

I followed a few groovy examples for implementing events but none that I found actually solved the problem.

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