简体   繁体   中英

Blazor Two Way Binding Text Area inside component

I am trying to two-way bind a text area inside a child component in Blazor and I just can't figure it out.

Parent

@page "/test"

<h3>Parent Component</h3>
<input type="text" @bind="mydata" />

<TWBTextArea @bind-ChildData=@mydata></TWBTextArea>

@code {
    public string mydata = "test";
}

Child

<h4>Child Component</h4>

<textarea @bind=@ChildData></textarea>

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

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

When I update from the parent component, the child textarea updates, but when I update the child text area, the parent is not updated.

Additional note: If I change the value being passed from a string to an object with a string property and I pass that object to the Child Component, two way binding DOES work but only after an update to the parent component.

Thanks in advance for any help!

Important: You should not bind to components' parameters as it may have side-effects on your app. Read this post by Steve Sanderson

Note that I define a local variable, named data , into which I assign the ChildData parameter property's value from the OnParametersSet method. That is done, as I've said before, in order to refrain from binding to a component's parameter.

Since we are creating a two-way data-binding, the value attribute of the textarea element is bound to the variable data . The flow of data is from the variable to the element. We also need to create an event handler, named here HandleOnChange , whose role is to update the local variable data , as well as to invoke the EventCallback 'delegate', passing the new value stored in the data variable. This value is gladly received in the parent component's mydata field, after which, a re-rendering occurs to reflect the new changes.

Note that I'm using the input event, instead of the change event, to make life easier and more interesting.

Child component

<h4>Child Component</h4>

<textarea @oninput="HandleOnChange">@data</textarea>

@code {

    private string data;

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

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

    private async Task HandleOnChange(ChangeEventArgs args)
    {
        data = args.Value.ToString();

        await ChildDataChanged.InvokeAsync(data);
    }

    protected override void OnParametersSet()
    {
        data = ChildData;

        base.OnParametersSet();
    }
}

Usage

@page "/test"

<h3>Parent Component</h3>
<input type="text" @bind="mydata" @bind:event="oninput" />

<ChildComponent @bind-ChildData="mydata" />

@code {
    private string mydata = "test";
}

I seem to have it working now by inheriting InputBase and binding to the CurrentValue property, but it was definitely something of an uphill battle.

@inherits InputBase<string>


<textarea class="@Class" @bind="CurrentValue"
    @attributes="AdditionalAttributes" />


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

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

    protected override bool TryParseValueFromString(string value, out string result, out string validationErrorMessage)
    {
        result = value;
        validationErrorMessage = null;
        return true;
    }
}

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