当TextChanged时Blazor InputText调用异步方法

时间:2019-11-28 15:41:06

标签: blazor

我尝试捕获Blazor(ServerSide)中InputText的文本更改,然后调用一个异步方法来检查输入是否正确的优惠券代码。

HTML:

<EditForm Model="@Basket" OnValidSubmit="@CommitBasket">
    Gutscheincode
    <InputText class="coupon-input checkout-control pristine untouched" 
            @bind-Value="CouponCode"
            @onchange="CouponCodeChanged">
    </InputText>
    @CouponText
</EditForm>`

但是未引发CouponCodeChanged-OnKeyUp没用,因为在该状态下文本值未更改...

这是C#方法:

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}";
}

有没有人提示或想法如何方便地解决该问题?

谢谢!

4 个答案:

答案 0 :(得分:2)

InputText组件没有onchange事件,但是有ValueChanged
但是,如果要预订此事件,则需要传递一个ValueExpression,这并不容易。 我发现预订此事件的最简单方法是覆盖InputText组件。

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);
  }
}

用法

<EditForm Model="@Basket" OnValidSubmit="@CommitBasket">
    Gutscheincode
    <CouponComponent @bind-Value="CouponCode"
        @CouponValueChanged="CouponCodeChanged">
    </InputText>
    @CouponText
</EditForm>

@code {
   private void CouponCodeChanged(string coupon)
   {
      CouponText = coupon;
      StateHasChanged();
   }
}

答案 1 :(得分:1)

这对我有用...

@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";

        }
    }

您也可以通过KeyUp事件来做到这一点:

<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();

    }
}

答案 2 :(得分:1)

我创建了一组Blazor components。其中之一是Debounced inputs,具有多种输入类型和更多功能。 Blazor.Components.Debounce.Input可在NuGet上使用。

您可以使用demo app进行尝试。

注意:当前处于预览状态。最终版本随.NET 5一起发布。

答案 3 :(得分:0)

尝试一下:

@onchange="(ChangeEventArgs _event) => CouponCodeChanged(_event.Value.ToString())"

更新方法:

public async Task CouponCodeChanged(string coupon)
...
..., AppState.BaseUrl, 2, coupon);
...