0

我对 Blazor 相当陌生。我正在尝试通过引用页面在 EditForm 中呈现自定义组件。

但是当我提交没有值的表单时,边框颜色不会变为红色。此外,在清除输入值后提交表单时,边框不会变为红色。它保持绿色。

截屏:

图片

代码片段

NativeTextboxComponent.razor

<InputText @bind-Value="@Value" class="form-control" />

@code {
 public string _Value;
    [Parameter]
    public string Value
    {
        get
        {
            return _Value;
        }
        set
        {
            if (_Value != value)
            {
                ValueChanged.InvokeAsync(value);
            }
            _Value = value;
        }
    }
    [Parameter]
    public EventCallback<string> ValueChanged { get; set; }

}
}

索引.razor

<EditForm Model="@model" OnInvalidSubmit="HandleValidSubmit">
    <DataAnnotationsValidator />
    <NativeTextBoxComponent @bind-Value="@model.NativeValue"></NativeTextBoxComponent>
    <ValidationMessage For="() => model.NativeValue" />
    <button type="submit">Submit</button>
</EditForm>

public class Countries
    {
        [Required]
        public string Values { get; set; }
        [Required]
        public string LastName { get; set; }
        [Required]
        public string NativeValue { get; set; }
    }
    public Countries model = new Countries();

FieldCssClass 在这种情况下返回修改后有效。

图片

任何帮助将不胜感激。

4

4 回答 4

1

要了解为什么 FieldCssClass 返回有效而 ValidationMessage 返回无效,请务必观察您的组件 NativeTextboxComponent 对验证过程所做的事情。

在您的示例中,如果您将 NativeTextBoxComponent 更改为 InputText,它将正常工作。那是因为@bind-value 设置了InputBase的ValueExpression。这个属性不是一个简单的字符串,而是一个表达式。此表达式用于从您的模型中获取属性,例如Required。

如果您使用<NativeTextBoxComponent @bind-Value="@model.NativeValue"></NativeTextBoxComponent> 一个简单的字符串绑定到该组件。它已经失去了与其属性的联系。双向绑定仍然有效。如果您的组件更改了字符串,则将其写回对象。<ValidationMessage For="() => model.NativeValue" /> 如果没有字符串,这就是您返回错误的原因。但同样,从嵌套的角度来看,<InputText @bind-Value="@Value" class="form-control" />它只是一个字符串。

要解决您的问题,您的组件可以从 InputBase 继承,并且您可以创建自定义布局。

@using System.Diagnostics.CodeAnalysis;

@inherits InputBase<string>

<input @attributes="AdditionalAttributes" class="@CssClass" @bind-value="CurrentValue" />

@code {

    protected override bool TryParseValueFromString(string? value, out string? result, [NotNullWhen(false)] out string? validationErrorMessage)
    {
        result = value;
        validationErrorMessage = null;
        return true;
    }
}
于 2020-11-12T16:55:15.943 回答
0

我认为您缺少放置所需字段的模型。这是此处文档中的示例

using System.ComponentModel.DataAnnotations;

public class ExampleModel
{
    [Required]
    [StringLength(10, ErrorMessage = "Name is too long.")]
    public string Name { get; set; }
}
于 2020-11-13T03:24:31.053 回答
0

ValueExpression 被定义为参数,因此父组件模型不会更新为子组件表达式,因此 FieldIdentifier cssClass 中的模型值不会更新。在editform中渲染自定义组件时,直接调用invokeAsync和value表达式(不需要使用二绑定(@bind-Value))。

索引剃刀

<EditForm Model="@model">
      <DataAnnotationsValidator />
      <h5>TextBox : @model.FirstName</h5>
    <NativeTextBoxComponent @bind-Value="@model.FirstName" InputHandler="@inputHandler"> </NativeTextBoxComponent >
    <ValidationMessage For="() => model.FirstName" />
   <SfButton CssClass="e-small e-info" Type="submit" Content="Submit"></SfButton>
</EditForm>
@code {
public class Countries
{
    [Required]
    public string FirstName { get; set; }
}
public Countries model = new Countries();

private void inputHandler(ChangeEventArgs args)
{
    model.FirstName = (string)args.Value;
}

}

NativeTextboxComponent.razor

<InputText Value="@Value" ValueChanged="ValueChanged" @oninput="@InputHandler" ValueExpression="@ValueExpression"></InputText>
@code
{ 
private string _value { get; set; }
[Parameter]
public string ID { get; set; }
[Parameter]
public Expression<Func<string>> ValueExpression { get; set; }
[Parameter]
public string Value
{
    get => _value;
    set
    {
        if (!EqualityComparer<string>.Default.Equals(value, _value))
        {
            _value = value;
            ValueChanged.InvokeAsync(value);
        }
    }
}
[Parameter]
public EventCallback<string> ValueChanged { get; set; }
[Parameter]
public EventCallback<ChangeEventArgs> InputHandler { get; set; }

}
于 2020-11-14T06:49:15.583 回答
0

只是本诺的回答准确地解释了为什么你有这个问题

但是,您仍然可以使用 InputText 组件。

相应地修改您的 NativeTextboxComponent.razor :

<InputText Value="@Value" ValueChanged="@(v => Value = v)" ValueExpression="ValueExpression" class="form-control" />

@code {
 public string _Value;
    [Parameter]
    public string Value
    {
        get
        {
            return _Value;
        }
        set
        {
            if (_Value != value)
            {
                ValueChanged.InvokeAsync(value);
            }
            _Value = value;
        }
    }

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

    //Name of your property + 'Expression'
    [Parameter]
    public Expression<Func<string>> ValueExpression { get; set; }
}
于 2021-11-25T13:37:52.863 回答