我在Blazor WASM客户端应用程序中遇到了验证无法正常工作的问题。
将InputText元素封装到一个组件中以实现紧凑的布局,不再执行验证,否则会正确执行。
使用像
public class Customer {
[Required]
[StringLength(100)
public string customerName {get; set;} = "";
}
形式
<EditForm Model=@customer>
<DataAnnotationsValidator />
<ValidationSummary />
<div class="form-row">
<div class="form-group mb-0 col-sm-12">
<div class="input-group input-group-sm mb-1 mt-1">
<div class="input-group-prepend">
<span class="input-group-text" style="width:6em;">Firma</span>
</div>
<InputText type="text" class="form-control" @bind-Value=customer.customerName />
</div>
</div>
</EditForm>
验证工作正常
但是为了模块化,我将内部的东西外包给一个单独的组件。
@page "/inputGroup"
<div class="input-group input-group-sm mb-1 mt-1">
<div class="input-group-prepend">
<span class="input-group-text" style="width:6em;">@label</span>
</div>
<InputText type=@type class="form-control" @bind-Value=@data @oninput=@onChange />
</div>
@code {
[Parameter]
public string label {get; set;} = "Label:";
[Parameter]
public string type {get; set;} = "text";
[Parameter]
public string data {get; set;} = "";
[Parameter]
public EventCallback<string> dataChanged {get; set;}
private Task onChange(ChangeEventArgs e) {
data = (string)e.Value;
return dataChanged.InvokeAsync(data);
}
}
然后我把这个放到我的表格里,比如
...
<div class="form-row">
<div class="form-group mb-0 col-sm-12">
<InputGroup label="Firma:" @bind-data=customer.customerName />
</div>
</div>
...
验证无法正常工作!?
我认为你的做法是错误的,也是复杂的。它应该是简单的,没有不必要的约束等。
这里有一个工作示例代码,它演示了如何创建一个EditForm,其中嵌入组件,一起工作,并共享同一个Model对象。简而言之,你可以把它看成是全部的EditForm。
<div class="form-group">
<label for="body">Text: </label>
<InputTextArea Id="body" Class="form-control" @bind-Value="@Model.Text">
</InputTextArea>
<ValidationMessage For="@(() => Model.Text)" />
</div>
<p>
<button class="btn btn-success" type="submit">
Submit
</button>
</p>
@code{
[Parameter]
public Comment Model { get; set; }
}
正如你可能已经注意到的,我们将Model传递给子组件。
<p>Leave me a comment</p>
<EditForm EditContext="@EditContext" OnValidSubmit="HandleValidSubmit">
<DataAnnotationsValidator />
<div class="form-group">
<label for="name">Name: </label>
<InputText Id="name" Class="form-control" @bind-Value="@Model.Name">
</InputText>
<ValidationMessage For="@(() => Model.Name)" />
</div>
<ChildComponent Model="@((Comment)EditContext.Model)">
</ChildComponent>
</EditForm>
@code
{
private EditContext EditContext;
private Comment Model = new Comment();
protected override void OnInitialized()
{
EditContext = new EditContext(Model);
base.OnInitialized();
}
public async Task HandleValidSubmit()
{
// do stuff ...
}
}
正如你所看到的,EditForm包含了一个单一的绑定文本框,而子组件包含了另一个字段和提交按钮。你可以以各种方式使用它,它表现为一个单一的实体。事情是将模型作为参数传递。你可以用其他方式来做。但这是另一个故事。
请注意,你尝试采取的方向是我们在Blazor Web Forms之前的编码方式,你需要绑定到各种对象,引发事件来更新对象等等。
希望能帮到你...