问题
I try to capture text changes of InputText in Blazor (ServerSide) and then call a async method to check if input is correct coupon code or not.
HTML:
<EditForm Model="@Basket" OnValidSubmit="@CommitBasket">
Gutscheincode
<InputText class="coupon-input checkout-control pristine untouched"
@bind-Value="CouponCode"
@onchange="CouponCodeChanged">
</InputText>
@CouponText
</EditForm>`
But The CouponCodeChanged isn't raised - OnKeyUp is not useful because the Text Value isn't changed at that state...
here is C# Method:
public async Task CouponCodeChanged(ChangeEventArgs args)
{
using var client = ClientFactory.CreateClient();
var result = await ApiCalls.GetCouponCodeData(client, AppState.BaseUrl, 2, CouponCode);
CouponText = result== null ? "NOT FOUND" : $"exists:{result.Exists} amount:{result.Amount}";
}
Has anyone a hint or idea how to solve that in a convinient way?
Thx!
回答1:
InputText
component doesn't have a onchange
event but ValueChanged
.
However, if you want to subscribe to this event you need to pass a ValueExpression
and it's not easy.
The easiest I found to subscribe to this event is to override the InputText
component.
CouponComponent.razor
@inherits InputText
<InputText class="coupon-input checkout-control pristine untouched"
ValueExpression="ValueExpression" Value="@Value" ValueChanged="OnValueChanged" />
@code {
[Parameter]
public EventCallback<string> CouponValueChanged { get; set; }
private async Task OnValueChanged(string value)
{
await ValueChanged.InvokeAsync(value);
using var client = ClientFactory.CreateClient();
var result = await ApiCalls.GetCouponCodeData(client, AppState.BaseUrl, 2, CouponCode);
var coupon = result == null ? "NOT FOUND" : $"exists:{result.Exists} amount:{result.Amount}"
await CouponValueChanged.InvokeAsync(coupon);
}
}
Usage
<EditForm Model="@Basket" OnValidSubmit="@CommitBasket">
Gutscheincode
<CouponComponent @bind-Value="CouponCode"
@CouponValueChanged="CouponCodeChanged">
</InputText>
@CouponText
</EditForm>
@code {
private void CouponCodeChanged(string coupon)
{
CouponText = coupon;
StateHasChanged();
}
}
回答2:
This is working for me...
@using System.Linq.Expressions
<p>@Coupon Text: @CouponText</p>
<EditForm Model="@basket" OnValidSubmit="@CommitBasket">
Gutscheincode
<InputText class="coupon-input checkout-control pristine untouched" Value="@basket.CouponCode" ValueChanged="@CouponCodeChanged" ValueExpression="@(() => basket.CouponCode)" />
</EditForm>
@code {
private Basket basket = new Basket();
private string CouponText;
private string _value { get; set; }
[Parameter]
public string Value
{
get { return _value; }
set
{
if (_value != value)
{
_value = value;
if (ValueChanged.HasDelegate)
{
ValueChanged.InvokeAsync(value);
}
}
}
}
[Parameter] public EventCallback<string> ValueChanged { get; set; }
[Parameter] public Expression<Func<string>> ValueExpression { get; set; }
private void CouponCodeChanged(string CouponCode)
{
basket.CouponCode = CouponCode;
CouponText = basket.CouponCode;
}
private void CommitBasket()
{ }
public class Basket
{
public Basket() { }
public string CouponCode { get; set; } = "12345";
public string CouponName { get; set; } = "Coupon Name";
}
}
You can also do it with the KeyUp event:
<InputText Id="CouponCode" Class="form-control" @bind-Value="@basket.CouponCode" @onkeyup='@(e => KeyUp(e, "CouponCode"))'></InputText>
@code {
private EditContext EditContext;
private Basket basket = new Basket();
protected override void OnInitialized()
{
EditContext = new EditContext(basket);
base.OnInitialized();
}
void KeyUp(KeyboardEventArgs e, string memberName)
{
var property = basket.GetType().GetProperty(memberName);
var value = property.GetValue(basket);
// Requires some tweaks to prevent unwanted stuff...
property.SetValue(basket, value + e.Key);
var id = EditContext.Field(memberName);
EditContext.NotifyFieldChanged(id);
property = basket.GetType().GetProperty(memberName);
CouponText = property.GetValue(basket).ToString();
}
}
回答3:
Try this:
@onchange="(ChangeEventArgs _event) => CouponCodeChanged(_event.Value.ToString())"
Update method:
public async Task CouponCodeChanged(string coupon)
...
..., AppState.BaseUrl, 2, coupon);
...
回答4:
I have created a set of Blazor components. One of which is Debounced inputs with multiple input types and much more features. Blazor.Components.Debounce.Input is available on NuGet.
You can try it out with the demo app.
Note: currently it is in Preview. Final version is coming with .NET 5. release
来源:https://stackoverflow.com/questions/59092278/blazor-inputtext-call-async-method-when-textchanged