Reputation: 605
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.
Upvotes: 10
Views: 19256
Reputation: 123
The current version of Blazor seems to have what you need. <InputTextArea @bind-Value="@prospect.Notes" Style="width:800px;height:200px;word-wrap:normal;" /> seems to work!
Documentation: https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.forms.inputtextarea?view=aspnetcore-8.0
Upvotes: 7
Reputation: 7261
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;
}
}
Upvotes: 1
Reputation: 45586
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.
<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();
}
}
@page "/test"
<h3>Parent Component</h3>
<input type="text" @bind="mydata" @bind:event="oninput" />
<ChildComponent @bind-ChildData="mydata" />
@code {
private string mydata = "test";
}
Upvotes: 16