Quantcast
Channel: Active questions tagged blazor - Stack Overflow
Viewing all articles
Browse latest Browse all 4839

Data binding in Blazor: How to propagate values out of a component?

$
0
0

I have a fairly simple component, which looks like this:

<form><div class="form-group"><label for="sampleText">Sample Text</label><input type="text"               class="form-control"               id="sampleText"               aria-describedby="sampleTextHelp"               placeholder="Enter a text"               @bind="@Value" /><small id="sampleTextHelp" class="form-text text-muted">Enter a text to test the databinding</small></div></form><p>You entered here: @Value</p>@code {    [Parameter]    public string Value { get; set; }}

I now add this to a page like this:

<MVVMTest Value="@_value" /><p>    You entered in MVVMTest:    @_value</p>@functions {    private string _value;}

When I enter text in the input field, it is correctly updated at You entered here: but not propagated to *You entered in MVVMTest":

MVVM not working

What do I have to do to get this correctly propagated?

I could think of hooking up an Action<string> as a second [Parameter] which I fire inside the component when the text is changed, but it seems like a hackish and roundabout way. Is it how it has to be done, or is there a better way?

Followup 1

The answer from Issac does not work because it stumbles over @bind-value:oninput="@((e) => ValueChanged.Invoke(e.Value))" with Cannot convert lambda expression to type 'object' because it is not a delegate type.

I had to do it in this roundabout way:

<form><div class="form-group"><label for="sampleText">Sample Text</label><input type="text"               class="form-control"               id="sampleText"               aria-describedby="sampleTextHelp"               placeholder="Enter a text"               @bind="@Value" /><small id="sampleTextHelp" class="form-text text-muted">Enter a text to test the databinding</small></div></form><p>You entered here: @Value</p>@code {    private string _value;    [Parameter]    public string Value {        get => _value;        set {            if(Equals(value, _value)) {                return;            }            _value = value;            OnValueChanged.InvokeAsync(value).GetAwaiter().GetResult();        }    }    [Parameter]    public EventCallback<string> OnValueChanged { get; set; }}

And using it like:

@inject HttpClient http@page "/test"<div class="top-row px-4">    Test Page</div><div class="content px-4"><MVVMTest Value="@_value" OnValueChanged="@(v => _value = v)" /><p>        You entered in MVVMTest:        @_value</p></div>@functions {    private string _value;}

Not pretty, but it works. My "real" component is more complicated as a changed value triggers calls to the underlying ASP.net Core Service so I have to do elaborate detection who changes what to avoid infinite loops.

It would surely be better if Blazor supported XAML/WPF-like MVVM though...

Followup 2

I came back to Issac's solution and with an extra cast, I got it working:

<form><div class="form-group"><label for="sampleText">Sample Text</label><input type="text"               class="form-control"               id="sampleText"               aria-describedby="sampleTextHelp"               placeholder="Enter a text"               value="@Value"               oninput="@((Func<ChangeEventArgs, Task>)(async e => await OnValueChanged.InvokeAsync(e.Value as string)))" /><small id="sampleTextHelp" class="form-text text-muted">Enter a text to test the databinding</small></div></form><p>You entered here: @Value</p>@code {    private string _value;    [Parameter]    public string Value { get; set; }    [Parameter]    public EventCallback<string> OnValueChanged { get; set; }}

Usage:

<MVVMTest Value="@_value" OnValueChanged="@(v => _value = v)" /><p>    You entered in MVVMTest:    @_value</p>@functions {    private string _value;}

This is already a known issue in Blazor. I tripped over this last week already, and I posted the workaround in the VS developer forum as well.


Viewing all articles
Browse latest Browse all 4839

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>