gpt4 book ai didi

blazor - 如何在组件中使用

转载 作者:行者123 更新时间:2023-12-05 03:46:35 25 4
gpt4 key购买 nike

Please note that although this is closely related to this question, the answer there is specific to one known model property, whereas I want this to work for any property, so the component is reusable.

我想使用 Blazor <ValidationMessage>组件内的标记。但是,当我这样做时,不会显示验证消息。

例如,以下组件 ( FormRowText.razor ) 创建包含 <input type="text /> 的行(在 Bootstrap 网格意义上)对于模型上的命名属性...

<div class="form-group row">
<label for="@PropertyName" class="col-lg-2 col-form-label">@(Caption ?? PropertyName)</label>
<div class="col-lg-10 input-group">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="far fa-@Icon"></i>
</span>
</div>
<input class="form-control" Value="@Value" type="text"
id="@PropertyName" name="@PropertyName" @onchange="@OnChanged" />
</div>
</div>

@code {

[Parameter]
public string PropertyName { get; set; }

[Parameter]
public string Value { get; set; }

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

[Parameter]
public string Caption { get; set; }

[Parameter]
public string Icon { get; set; }

private async Task OnChanged(ChangeEventArgs cea) =>
await ValueChanged.InvokeAsync(cea.Value?.ToString() ?? "");

}

它是这样使用的...

<EditForm ...>
<FormRowText PropertyName="@nameof(Customer.Email)" @bind-Value="_customer.Email" Icon="at" />
</EditForm>

如果我添加 <ValidationMessage>在这个标记之后,它工作正常,但如果我将它添加到组件中(这是我想要它的位置),它就不起作用。

我看到了this answer来自@enet,它展示了如何针对特定的已知模型属性执行此操作。但是,我的组件设计用于任何模型属性,我不确定如何修改它。

我尝试为模型添加一个参数(在文件顶部使用 @typeparam T)...

[Parameter]
public T Model { get; set; }

...并在 HTML 中添加以下内容...

<ValidationMessage For="() => PropertyName" />

但是这不起作用。

有什么想法吗?

最佳答案

您可以将 EditContext 级联到您的组件并使用它来通知当前字段已更改

FormRowText.razor.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;

public partial class FormRowText
{
[CascadingParameter] EditContext CascadedEditContext { get; set; }

[Parameter]
public string PropertyName { get; set; }

[Parameter]
public string Value { get; set; }

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

[Parameter]
public string Caption { get; set; }

[Parameter]
public string Icon { get; set; }

[Parameter] public Expression<Func<string>> ValueExpression { get; set; }
private async Task OnChanged(ChangeEventArgs cea)
{
await ValueChanged.InvokeAsync(cea.Value?.ToString() ?? "");
var identifier = CascadedEditContext.Field(PropertyName);
CascadedEditContext.NotifyFieldChanged(identifier);
}

}

FormRowText.razor

<div class="form-group row">
<label for="@PropertyName" class="col-lg-2 col-form-label">@(Caption ?? PropertyName)</label>
<div class="col-lg-10 input-group">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="far fa-@Icon"></i>
</span>
</div>
<input class="form-control" value="@Value" type="text" id="@PropertyName" name="@PropertyName"
@onchange="@OnChanged" />
<ValidationMessage For="@ValueExpression" />

</div>
</div>

你还需要

public class Customer
{
[Required]
public string Name { get; set; }
public Country Country { get; set; } = Country.Israel;
[Required]
[DataType(DataType.EmailAddress)]
[EmailAddress]
public string Email { get; set; }
}

用法

@page "/"


@using System.ComponentModel.DataAnnotations;
@using Microsoft.AspNetCore.Components.Forms;


<EditForm EditContext="EditContext" OnValidSubmit="HandleValidSubmit">
<DataAnnotationsValidator />

<div class="form-group">
<label for="name">Name: </label>
<InputText @bind-Value="@customer.Name"></InputText>
<ValidationMessage For="@(() => customer.Name)" />

</div>
<div class="form-group">
<FormRowDropdownEnum @bind-Value="customer.Country" Caption="Country" T="Country"></FormRowDropdownEnum>
<ValidationMessage For="@(() => customer.Country)" />
<FormRowText @bind-Value="customer.Email" Caption="Email"
PropertyName="@nameof(Customer.Email)" Icon="at"></FormRowText>


</div>
<p>
<button type="submit" class="btn btn-primary">Save</button>

</p>
</EditForm>



@code{
private Customer customer = new Customer();
private EditContext EditContext;

protected override void OnInitialized()
{
EditContext = new EditContext(customer);

}

public async Task HandleValidSubmit()
{
await Task.Delay(1);

Console.WriteLine("Saving...");

}
}

另一个版本

当您使用 EditForm 组件时,最好使用 Forms 组件,例如 InputText 组件等。

以下代码片段描述了如何通过对 InputText 组件进行子类化并添加新属性来实现 FormRowText 组件。请注意,组件的功能不需要 PropertyName

FormRowText2.razor

@inherits InputText

<div class="form-group row">
<label for="@PropertyName" class="col-lg-2 col-form-label">@(Caption ?? PropertyName)</label>
<div class="col-lg-10 input-group">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="far fa-@Icon"></i>
</span>
</div>
<input class="form-control" @bind="CurrentValue" type="text" id="@PropertyName" name="@PropertyName" />
<ValidationMessage For="@ValueExpression" />
</div>
</div>

@code{
[Parameter]
public string Caption { get; set; }

[Parameter]
public string Icon { get; set; }

[Parameter]
public string PropertyName { get; set; }

}

关于blazor - 如何在组件中使用 <ValidationMessage>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65224446/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com