如果值在 Blazor 中无效,则重置输入字段值

Reset input field value if value is invalid in Blazor

我在 for 循环中绑定了一些文本字段。

<Input type="text" @onchange='(ChangeEventArgs e)=>DataChange(e,item)' value="@item.value" />

在这里,如果用户在输入字段中键入任何内容,我在 DataChange 函数中有一个自定义验证。

private void DataChange(ChangeEventArgs e, PnL pnl)
  {
    if(e.Value.ToString().Contains(10))
     {
       pnl.value = e.Value.ToString();
     }
  }

如果更改有效,那么我只会为列表中的项目赋值。 但如果它无效我需要将值重置为原始值。

我试过打电话给 StateHasChange() 但没有用。 有人可以帮忙吗?

@onchange发生时,绑定已经结束,所以此时无效的字符串在pnl.value.

其中一个解决方案可能是额外 属性 用于绑定。 value 属性 只有在 tempVal 有效时才会改变,否则会重置 tempVal:

<input type="text" @bind-value="item.tempVal" />

@code {
    PnL item = new() { value = "hello10hi", tempVal = "hello10hi" };//valid values
    class PnL
    {
        public string value { get; set; }
        string _tempVal;
        public string tempVal { get => _tempVal; set { _tempVal = value; DataChange(value, this); } }

        void DataChange(string newVal, PnL pnl)
        {
            if (newVal.Contains("10"))//is valid
            {
                pnl.value = newVal;
            }
            else
            {
                pnl.tempVal = pnl.value;
            }
        }
    }

}

编辑 (代码已更新)

问题是,tempVal在写入时没有更新,所以它仍然有默认值,所以在分配value后没有改变,因此在[=35=中没有更新].

使用 bind-valuetempVal 将始终更新。 “问题”是我们丢失了 onechange 代码(因为我们使用 bind)。因此,我不得不与 tempVal 属性.

内部的更改进行交互

试试这个:

private async Task DataChange(ChangeEventArgs e, PnL pnl)
  {
    if(e.Value.ToString().Contains(10))
     {
       pnl.value = e.Value.ToString();
     }
else
  {
    var tempValue = pnl.value;
    pnl.value = string.Empty();
    await Task.Yield();
    pnl.value = tempValue;
  }
 }

所以这里发生的事情是这样的。

  1. 代码 运行 与 await Task.Yield 同步。
  2. 此时pnl.value为空字符串
  3. DataChange 执行 Blazor 事件处理程序,它将渲染操作加载到渲染器队列。
  4. Yield 允许渲染器为其渲染队列提供服务,并重新渲染组件。 pnl.value 为空白 - 与上次渲染不同 - 因此输入在 DOM.
  5. 中更新
  6. yield 之后的代码现在 运行 完成,设置 pnl.value 回到它的原始值。
  7. DataChange 完成并且 Blazor 事件处理程序将第二个渲染操作加载到渲染器队列上,该渲染器队列现在在值再次更改时重新渲染输入。

在您的代码中,所有内容 运行 都是同步的。您可以根据需要多次调用 StateHasChanged,渲染器只会在 运行 完成 DataChange 后获得任务时间。此时渲染器仍然认为输入设置为 pnl.value 的原始值(不是编辑后的值),因此 DOM 不会更新。

CodeProject 上有一篇文章更详细 - https://www.codeproject.com/Articles/5310624/Blazor-UI-Events-and-Rendering