【发布时间】:2020-05-17 18:18:44
【问题描述】:
我正在开发 Blazor Wasm。我想创建自己的自定义 select 组件。下面的实现有效,但缺少一些东西:在我的自定义选择组件中选择某些内容时没有回调。我希望能够从我的 TestView.razor 组件中捕获事件。
我的自定义实现 InputSelectCustom.cs
public class InputSelectCustom<T> : InputSelect<T>
{
protected override string FormatValueAsString(T value)
{
// Custom code ommitted for clarity
return base.FormatValueAsString(value);
}
protected override bool TryParseValueFromString(string value, out T result, out string validationErrorMessage)
{
if (typeof(T) == typeof(int) ||
typeof(T) == typeof(int?))
{
if (int.TryParse(value, out var resultInt))
{
result = (T)(object)resultInt;
validationErrorMessage = null;
return true;
}
else
{
result = default;
validationErrorMessage = "The chosen value is not valid.";
return false;
}
}
else
if (typeof(T).IsEnum)
{
if (CustomFunctions.EnumTryParse<T>(value, out var resultEnum))
{
result = (T)(object)resultEnum;
validationErrorMessage = null;
return true;
}
else
{
result = default;
validationErrorMessage = "The chosen value is not valid.";
return false;
}
}
else
if (typeof(T).IsNullableEnum())
{
if (CustomFunctions.NullableEnumTryParse<T>(value, out var resultEnum))
{
result = (T)(object)resultEnum;
validationErrorMessage = null;
return true;
}
else
{
result = default;
validationErrorMessage = "The chosen value is not valid.";
return false;
}
}
else
{
return base.TryParseValueFromString(value, out result, out validationErrorMessage);
}
}
protected override Task OnParametersSetAsync()
{
return base.OnParametersSetAsync();
}
}
我的 TestView.razor
@page "/test-view"
<EditForm Model="CurrentFilterModel">
<InputSelectCustom @bind-Value="@CurrentFilterModel.ClassmentFilter">
<option value="null"> Show all content </option>
<option value="@EnumClassment.Popular"> Popular </option>
<option value="@EnumClassment.Featured"> Featured </option>
<option value="@EnumClassment.Novelty"> Novelty </option>
</InputSelectCustom>
</EditForm>
@code
{
public FilterModel CurrentFilterModel = new FilterModel();
public class FilterModel
{
public EnumClassment? ClassmentFilter { get; set; }
}
}
我的枚举:
public enum EnumClassment
{
Featured,
Popular,
Novelty
}
更新
所以我需要一种在我选择的值发生变化时得到通知的方法。
起初,我尝试过:
<InputSelectCustom @bind-Value="CurrentFilterModel.ClassmentFilter">
<option value=""> Show all content </option>
<option value="@EnumClassment.Popular"> Popular </option>
<option value="@EnumClassment.Featured"> Featured </option>
<option value="@EnumClassment.Novelty"> Novelty </option>
</InputSelectCustom>
所选值已正确更改,但使用上面的代码,我无法收到值更改的通知。根据信息,我需要得到通知,因为每当用户更改选择时,我想立即执行服务器端调用以过滤数据。
下面是我的第二次尝试:
<InputSelectCustom @bind-Value="CurrentFilterModel.ClassmentFilter" ValueChanged="ValueChangedForClassmentFilter">
<option value=""> Show all content </option>
<option value="@EnumClassment.Popular"> Popular </option>
<option value="@EnumClassment.Featured"> Featured </option>
<option value="@EnumClassment.Novelty"> Novelty </option>
</InputSelectCustom>
如您所见,我不能同时使用@bind-Value 和ValueChanged。
所以这是我的最终解决方案:
<InputSelectCustom Value="@CurrentFilterModel.ClassmentFilter" ValueExpression="@( () => CurrentFilterModel.ClassmentFilter )" ValueChanged="@( (EnumClassment? s) => ValueChangedForClassmentFilter(s) )">
<option value=""> Show all content </option>
<option value="@EnumClassment.Popular"> Popular </option>
<option value="@EnumClassment.Featured"> Featured </option>
<option value="@EnumClassment.Novelty"> Novelty </option>
</InputSelectCustom>
protected async Task ValueChangedForClassmentFilter(EnumClassment? theUserInput)
{
// You have to update the model manually because handling the ValueChanged event does not let you use @bind-Value
// For the validation to work you must now also define the ValueExpression because @bind-Value did it for you
CurrentFilterModel.ClassmentFilter = theUserInput;
// Refresh data based on filters
await FilterCoursesServerSide();
}
这一次,一切都按预期工作:每当用户选择另一个值时,我都会收到新值的通知,我可以立即执行自定义代码。
如果我错了,或者由于我是 Blazor 的新手,或者我可能遗漏了什么,请纠正我。
PS:用字符串、整数和枚举测试。
【问题讨论】: