Blazor - 如何让子组件显示验证消息?
Blazor - How to make child component show validation messages?
如果嵌套组件未正确填充,我需要显示验证消息。该组件被其他父组件使用,他们需要获得有关是否存在验证问题的反馈。
我已经为嵌套组件尝试了以下代码并使用了 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();
}
}
这是我的父组件代码,减少了一些但重现了问题:
<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!";
}
}
}
testMessage
仅用于显示验证状态。
如何使父组件导致嵌套组件显示验证消息?我只能将 submit
放在父组件中。
按照要求,这是我正在做的一个更完整的例子,一个可以编辑的项目列表 内联 以及一个用于添加更多实例的表单. https://blazorrepl.com/repl/mlYwlQPm34bekYE824
我将尝试解释为什么您的方法不起作用,然后提出解决方法。希望我能正确理解你的意图。
首先您需要将 <input type="text" ...>
更改为 <InputText @bind-Value="..." />
当您的方法 buttonClick
在您的父组件中完成时,Blazor 将在您的组件上调用 StateHasChanged
。它是 EventHandler
的内置逻辑的一部分。这将触发子组件的组件生命周期。在那个循环中,子组件 属性 testModel
的 setter 将再次被调用。 Blazor 不对相等性进行任何测试。 (唯一强大的检查引擎是渲染周期结束时的 DiffierentialRenderTree
)。这意味着将创建一个新的 EditContext
。但是,此上下文不知道验证错误。因此消息消失。为了证明这一点,在 setter 中设置一个计数器变量并将其显示在页面上。你会看到这个结果。
.
为了避免这种情况,您创建一次 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();
}
}
如果您需要更新模型但保留验证状态,请写评论,我们可以从那里开始。
我有不同的方法..
您的 Parent 必须看起来像这样
<CascadingValue Value="testModel">
<EditForm Model="testModel">
<ChildComponent @ref="myTestComponent" />
<ObjectGraphDataAnnotationsValidator />
<ValidationMessage For="@(()=>testModel.Name)" />
<br />
<button type="submit">test</button>
</EditForm>
</CascadingValue>
您现在 Child 中唯一需要做的就是这样
@if (testModel != null)
{
<InputText @bind-Value="testModel.Name" />
}
@code {
[CascadingParameter]
public TestModel testModel { get; set; }
}
个人认为代码少...
最初的问题是分配 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!";
}
}
}
子组件:
@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();
}
}
如果嵌套组件未正确填充,我需要显示验证消息。该组件被其他父组件使用,他们需要获得有关是否存在验证问题的反馈。
我已经为嵌套组件尝试了以下代码并使用了 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();
}
}
这是我的父组件代码,减少了一些但重现了问题:
<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!";
}
}
}
testMessage
仅用于显示验证状态。
如何使父组件导致嵌套组件显示验证消息?我只能将 submit
放在父组件中。
按照要求,这是我正在做的一个更完整的例子,一个可以编辑的项目列表 内联 以及一个用于添加更多实例的表单. https://blazorrepl.com/repl/mlYwlQPm34bekYE824
我将尝试解释为什么您的方法不起作用,然后提出解决方法。希望我能正确理解你的意图。
首先您需要将 <input type="text" ...>
更改为 <InputText @bind-Value="..." />
当您的方法 buttonClick
在您的父组件中完成时,Blazor 将在您的组件上调用 StateHasChanged
。它是 EventHandler
的内置逻辑的一部分。这将触发子组件的组件生命周期。在那个循环中,子组件 属性 testModel
的 setter 将再次被调用。 Blazor 不对相等性进行任何测试。 (唯一强大的检查引擎是渲染周期结束时的 DiffierentialRenderTree
)。这意味着将创建一个新的 EditContext
。但是,此上下文不知道验证错误。因此消息消失。为了证明这一点,在 setter 中设置一个计数器变量并将其显示在页面上。你会看到这个结果。
为了避免这种情况,您创建一次 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();
}
}
如果您需要更新模型但保留验证状态,请写评论,我们可以从那里开始。
我有不同的方法.. 您的 Parent 必须看起来像这样
<CascadingValue Value="testModel">
<EditForm Model="testModel">
<ChildComponent @ref="myTestComponent" />
<ObjectGraphDataAnnotationsValidator />
<ValidationMessage For="@(()=>testModel.Name)" />
<br />
<button type="submit">test</button>
</EditForm>
</CascadingValue>
您现在 Child 中唯一需要做的就是这样
@if (testModel != null)
{
<InputText @bind-Value="testModel.Name" />
}
@code {
[CascadingParameter]
public TestModel testModel { get; set; }
}
个人认为代码少...
最初的问题是分配 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!";
}
}
}
子组件:
@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();
}
}