Blazor EditContext 不会触发 FieldState

Thi*_*rez 4 blazor blazor-client-side

Form组件中的值发生变化时。该Editform不验证,它不设置IsModifiedFieldState为true。只有在提交时才会验证。我看到当值改变时,类“修改”没有添加到 HTML 中的输入标签。所以看起来 EditContext 没有设置 FieldState?

我怎样才能做到这一点?

非常感谢!

代码(简体):

表单组件

@typeparam TItem

<EditForm EditContext="_editContext" OnValidSubmit="OnValidSumit">
    <DataAnnotationsValidator />
    <ValidationSummary />
    @ChildContent
</EditForm>


@code {
    [Parameter] public TItem Model { get; set; }
    [Parameter] public EventCallback OnValidSumit { get; set; }
    [Parameter] public RenderFragment ChildContent { get; set; }

    private EditContext _editContext;

    protected override void OnParametersSet()
    {
        _editContext = new EditContext(Model);
    }
}
Run Code Online (Sandbox Code Playgroud)

PS 当我使用OnInitialized而不是OnParametersSet,我得到修改后的类。但是接下来有一个问题DataAnnotationsValidator。这就像它没有看到 EditContext 的值,并且在值更改时始终有效或无效(在第一次提交之后)。

protected override void OnInitialized()
{
    _editContext = new EditContext(Model);
}
Run Code Online (Sandbox Code Playgroud)

父组件

<Form Model="someModel" OnValidSumit="Save">
    <InputNumber @bind-Value="Model.Number" />
    <InputText @bind-Value="Model.Name" />
    <button type="submit">Add</button>
</Form>

@code {
    public class SomeModel
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public SomeModel someModel = new SomeModel();
}
Run Code Online (Sandbox Code Playgroud)

Nik*_*k P 5

根据您在上面发布的内容并使用上面的代码重现您的问题,看起来可以调整几件事,您将再次工作。

Form.razor

@typeparam TItem

    <EditForm EditContext="_editContext" OnValidSubmit="HandleValidSubmit">
        <DataAnnotationsValidator />
        <ValidationSummary />
        @ChildContent
        <button type="submit" >Add</button>
        <button type="reset" >Reset</button>
    </EditForm>


@code {
    [Parameter] public TItem Model { get; set; }
    [Parameter] public EventCallback<TItem> OnValidSumit { get; set; }
    [Parameter] public RenderFragment ChildContent { get; set; }

    private EditContext _editContext;

    protected override void OnInitialized()
    {
        _editContext = new EditContext(Model);
    }

    async Task HandleValidSubmit()
    {
        await OnValidSumit.InvokeAsync(Model);
        _editContext = new EditContext(Model);
    }
}
Run Code Online (Sandbox Code Playgroud)

Form 组件的关键点是我移动<button>了表单内部,因此它不再作为子内容提供。其次,我确实OnInitialized()在启动时使用了该方法来初始化EditContext.

编辑第三,表单OnValidSubmit现在调用一个调用回调的私有方法,并且回调现在接受一个参数TItem。提交有效项目后,将等待事件回调,然后重置编辑上下文。

第四,Form 组件现在有一个用于对表单进行软重置的重置按钮。

父组件

@using System.ComponentModel.DataAnnotations 

@* Note the TItem in the line below, specified as the type needed for the EditContext *@

<Form TItem="SomeModel" Model="someModel" OnValidSumit="Save">

    <InputNumber @bind-Value="someModel.Id" />

    <InputText @bind-Value="someModel.Name" />

</Form>

@code {
    public class SomeModel
    {
        //ID can only be between 1 and 10, for demo purposes
        [Range(1,10, ErrorMessage ="ID must be between 1 and 10")]
        public int Id { get; set; }

        //Name is required and must be only letters
        [Required]
        [RegularExpression(@"^+[A-Za-z]+$", ErrorMessage ="Name can only contain letters")]
        public string Name { get; set; }
    }

    public SomeModel someModel = new SomeModel();

    void Save(SomeModel savedModel)
    {
        //do something useful with your model info
        MethodThatAcceptsSomeModel(savedModel);

        // If you want to reset the form, reinitialize the model
        someModel = new SomeModel();
    }
}
Run Code Online (Sandbox Code Playgroud)

Parent 组件的要点:

  1. 我为表单指定了“TItem”值。我发现有时通用组件在没有它的情况下也能工作,但我通过在其中添加它解决了很多问题。

  2. 我添加了“@using System.ComponentModel.DataAnnotations”行,然后向您的模型属性添加了一些数据注释装饰。您展示的实现只会检查不可解析的值,因此这样做增加了一些进一步的限制来测试验证。在这个设置中,“Name”属性只接受字母,不能为空,“Id”属性只接受 1 到 10 之间的值。

  3. 最后,当您离开表单字段时,此设置会生效。如果您想绑定到“输入”事件而不是默认的“更改”事件,以便在您键入时进行验证,请查看此链接以了解 MS 的官方文字,了解如何扩展其输入控件。

  4. 根据 OP 请求进行编辑以重置表单,该Save方法现在采用类型参数SomeModel并可以对其执行某些操作,然后重新初始化模型属性,这将重置表单。

希望这有帮助,让我知道。