Blazor - 如何使子组件显示验证消息?

jak*_*zon 5 razor blazor blazor-component

如果嵌套组件未正确填充,我需要显示验证消息。该组件由其他父组件使用,它们需要获得有关是否存在验证问题的反馈。

我已经为嵌套组件尝试了以下代码并使用了该CanSubmit方法。虽然该方法可以正确判断是否存在验证问题,但验证消息并未显示。

下面的所有代码都可以在blzorrepl上测试: https ://blazorrepl.com/repl/GvOQlvvv1789ra1G37

@if(editContext != null) {
    <EditForm EditContext="@editContext">
        <input type="text" @bind="testModel.Name" />
        <DataAnnotationsValidator />
        <ValidationSummary />
    </EditForm>
}

@code {
    [Parameter]
    public TestModel testModel
    {
        get { return (TestModel)editContext?.Model; }
        set { editContext = new EditContext(value); }
    }

    EditContext editContext;

    public bool CanSubmit()
    {
        return editContext.Validate();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的父组件代码,稍微减少但重现了问题:

<ChildComponent @ref="myTestComponent" testModel="testModel" />
<input type="button" @onclick="buttonClick" value="validate programmatically" />
<div>@testMessage</div>

@code {
    TestModel testModel = new TestModel();
    ChildComponent myTestComponent;
    string testMessage;

    void buttonClick()
    {
        testMessage = "not passed validation";

        if (myTestComponent.CanSubmit())
        {
            testMessage = "passed validation!";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

testMessage用于显示验证状态。

我该怎么做才能使父组件导致嵌套组件显示验证消息?我只能将其放在submit父组件中。

根据要求,这是我正在做的事情的更完整示例,可以内联编辑的项目列表以及用于添加更多实例的表单。https://blazorrepl.com/repl/mlYwlQPm34bekYE824

Jus*_*nno 5

我将尝试解释为什么您的方法不起作用,然后提出解决方法。我希望我正确理解你的意图。

首先你需要将其更改<input type="text" ...><InputText @bind-Value="..." />

当您的方法buttonClick在父组件中完成时,Blazor 将调用StateHasChanged您的组件。它是 的内置逻辑的一部分EventHandler。这将触发子组件的组件生命周期。在此周期中,子组件属性的设置器testModel将再次被调用。Blazor 不进行任何平等测试。(唯一强大的检查引擎是DiffierentialRenderTree在渲染周期结束时)。这意味着EditContext将创建一个新的。但是,此上下文不知道验证错误。因此该消息消失了。为了证明这一点,请在设置器内设置一个计数器变量并将其显示在页面上。您将看到这个结果。

在此输入图像描述

为了避免这种情况,您可以EditContext在设置参数时创建一次。

@code {

    [Parameter]
    public TestModel testModel { get; set; }

    EditContext editContext;

   protected override void OnParametersSet()
   {
       base.OnParametersSet();
       if(editContext == null)
       {
           editContext = new EditContext(testModel);
       }
   }

    public bool CanSubmit()
    {
        return editContext.Validate();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您需要更新模型但保留验证状态,请写一条注释,我们就可以从那里开始。

在此输入图像描述


jak*_*zon 4

最初的问题是分配EditContext. editForm.EditContext有必要访问它,但可以通过以下示例来完成。

工作示例https://blazorrepl.com/repl/Glkmbcbr323MP1VS55

父组件:

<ChildComponent @ref="myTestComponent" testModel="testModel" />
<input type="button" @onclick="buttonClick" value="validate programmatically" />
<div>@testMessage</div>

@code {
    TestModel testModel = new TestModel();
    ChildComponent myTestComponent;
    string testMessage;

    void buttonClick()
    {
        testMessage = "not passed validation";

        if (myTestComponent.CanSubmit())
        {
            testMessage = "passed validation!";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

子组件:

@if(testModel != null) {
    <EditForm @ref="editForm" Model="@testModel">
        <input type="text" @bind="testModel.Name" />
        <DataAnnotationsValidator />
        <ValidationSummary />
    </EditForm>
}

@code {
    [Parameter]
    public TestModel testModel
    {
        get; set;
    }

    EditForm editForm;

    public bool CanSubmit()
    {
        return editForm.EditContext.Validate();
    }
}
Run Code Online (Sandbox Code Playgroud)