Blazor 重置绑定值
Blazor resets bind value
我无法理解 blazor 绑定。我创建了一个基本示例来说明我面临的问题:
假设我想创建一个组件来选择这样的日期和时间:
,具有 DateTime 类型的 Value 属性。
首先,我创建一个组件来保存时间输入:
@* TimeInput.razor *@
<input type="time" @onchange=Changed value=@Value.ToString("HH:mm") required>
@code {
[Parameter] public DateTime Value { get; set; }
[Parameter] public EventCallback<DateTime> ValueChanged { get; set; }
public void Changed(ChangeEventArgs e)
{
Value = DateTime.Parse((string)e.Value!);
ValueChanged.InvokeAsync(Value);
}
}
然后我使用 select 输入和在上一步中创建的 TimeInput 组件创建一个组件:
@* DateTimeSelector.razor *@
<select @onchange=DateChanged>
@for (int i = 0; i < 7; i++)
{
var date = new DateTime(2022, 1, 1).AddDays(i);
<option value=@date.ToString("yyyy-MM-dd")
selected=@(Value.Date == date)>
@date.ToString("dddd")
</option>
}
</select>
<TimeInput Value=Value ValueChanged=TimeChanged />
@code
{
[Parameter] public EventCallback<DateTime> ValueChanged { get; set; }
private void DateChanged(ChangeEventArgs arg)
=> Value = DateTime.Parse((string)arg.Value!).Add(Value.TimeOfDay);
private void TimeChanged(DateTime time)
=> Value = Value.Date.Add(time.TimeOfDay);
private DateTime value;
[Parameter]
public DateTime Value
{
get => value;
set
{
Console.WriteLine($"Value is {value}"); // FOR DEBUGGING
if (this.value != value)
{
this.value = value;
ValueChanged.InvokeAsync();
}
}
}
}
最后,我在一个页面中进行测试:
@page "/"
<p><DateTimeSelector @bind-Value=@dateTime /></p>
<p>Debug: <input type="text" value=@dateTime /></p>
@code {
private DateTime dateTime = new DateTime(2022, 1, 3, 17, 0, 0);
}
加载页面时,组件按预期显示值 2022-01-03 17:00:
但是一旦用户更改值(例如,从下午 5 点到下午 6 点),该值就会重置为 0001-01-01 00:00:
如果我看一下控制台,我会看到:
那么为什么会这样呢?谁用默认日期为 属性 Value 调用(两次)setter?我该如何解决?
我有类似的问题,但没有找到合适的解决方案,所以我一直在寻找其他选择并发现了 Blazorise,它是一个组件库,其中包含 DateEdit 或 TimeEdit 等模块,可以解决您遇到的问题,它是替代方案,可能不是您所期望的,但使用起来非常简单!
<Field>
<FieldLabel>Date</FieldLabel>
<DateEdit TValue="DateTime?" Placeholder="Select Date" @bind-Date="@input.date"></DateEdit>
</Field>
嗯,只是一个小疏漏。在您的 DateTimeSelector
中,您必须使用值调用。
ValueChanged.InvokeAsync();
=> ValueChanged.InvokeAsync(value);
我无法理解 blazor 绑定。我创建了一个基本示例来说明我面临的问题:
假设我想创建一个组件来选择这样的日期和时间:
首先,我创建一个组件来保存时间输入:
@* TimeInput.razor *@
<input type="time" @onchange=Changed value=@Value.ToString("HH:mm") required>
@code {
[Parameter] public DateTime Value { get; set; }
[Parameter] public EventCallback<DateTime> ValueChanged { get; set; }
public void Changed(ChangeEventArgs e)
{
Value = DateTime.Parse((string)e.Value!);
ValueChanged.InvokeAsync(Value);
}
}
然后我使用 select 输入和在上一步中创建的 TimeInput 组件创建一个组件:
@* DateTimeSelector.razor *@
<select @onchange=DateChanged>
@for (int i = 0; i < 7; i++)
{
var date = new DateTime(2022, 1, 1).AddDays(i);
<option value=@date.ToString("yyyy-MM-dd")
selected=@(Value.Date == date)>
@date.ToString("dddd")
</option>
}
</select>
<TimeInput Value=Value ValueChanged=TimeChanged />
@code
{
[Parameter] public EventCallback<DateTime> ValueChanged { get; set; }
private void DateChanged(ChangeEventArgs arg)
=> Value = DateTime.Parse((string)arg.Value!).Add(Value.TimeOfDay);
private void TimeChanged(DateTime time)
=> Value = Value.Date.Add(time.TimeOfDay);
private DateTime value;
[Parameter]
public DateTime Value
{
get => value;
set
{
Console.WriteLine($"Value is {value}"); // FOR DEBUGGING
if (this.value != value)
{
this.value = value;
ValueChanged.InvokeAsync();
}
}
}
}
最后,我在一个页面中进行测试:
@page "/"
<p><DateTimeSelector @bind-Value=@dateTime /></p>
<p>Debug: <input type="text" value=@dateTime /></p>
@code {
private DateTime dateTime = new DateTime(2022, 1, 3, 17, 0, 0);
}
加载页面时,组件按预期显示值 2022-01-03 17:00:
但是一旦用户更改值(例如,从下午 5 点到下午 6 点),该值就会重置为 0001-01-01 00:00:
如果我看一下控制台,我会看到:
那么为什么会这样呢?谁用默认日期为 属性 Value 调用(两次)setter?我该如何解决?
我有类似的问题,但没有找到合适的解决方案,所以我一直在寻找其他选择并发现了 Blazorise,它是一个组件库,其中包含 DateEdit 或 TimeEdit 等模块,可以解决您遇到的问题,它是替代方案,可能不是您所期望的,但使用起来非常简单!
<Field>
<FieldLabel>Date</FieldLabel>
<DateEdit TValue="DateTime?" Placeholder="Select Date" @bind-Date="@input.date"></DateEdit>
</Field>
嗯,只是一个小疏漏。在您的 DateTimeSelector
中,您必须使用值调用。
ValueChanged.InvokeAsync();
=> ValueChanged.InvokeAsync(value);