后端更改后 InputDate 字段未更新

InputDate field not updating after backend change

我正在尝试制作一个允许您选择开始和结束日期的组件。当然,部分原因是开始日期不能早于结束日期,反之亦然。为此,我创建了以下组件:

@if (!IsDisabled)
{
    <div class="form-row">
        <div class="col">
            <label for="@($"startDate-{_id}")">Start datum</label>
            <InputDate class="form-control" id="@($"startDate-{_id}")" TValue="DateTime" Value="@StartDate" ValueChanged="@((e) => HandleStartDateChanged(e))" ValueExpression="(() => StartDate)" />
        </div>
        <div class="col">
            <label for="@($"endDate-{_id}")">Eind datum</label>
            <InputDate class="form-control" id="@($"endDate-{_id}")" TValue="DateTime" Value="@EndDate" ValueChanged="@((e) => HandleEndDateChanged(e))" ValueExpression="(() => EndDate)" />
        </div>
    </div>
}
else
{
    <div class="form-row">
        <div class="col">
            <label for="@($"startDate-{_id}")">Start datum</label>
            <input type="date" class="form-control" id="@($"startDate-{_id}")" @bind-value="@StartDate" disabled />
        </div>
        <div class="col">
            <label for="@($"endDate-{_id}")">Eind datum</label>
            <input type="date" class="form-control" id="@($"endDate-{_id}")" @bind-value="@EndDate" disabled />
        </div>
    </div>
}

@code{
    private string _id = Guid.NewGuid().ToString();

    [Parameter] public bool IsDisabled { get; set; }

    [Parameter] public DateTime StartDate { get; set; }
    [Parameter] public EventCallback<DateTime> StartDateChanged { get; set; }

    [Parameter] public DateTime EndDate { get; set; }
    [Parameter] public EventCallback<DateTime> EndDateChanged { get; set; }

    private void HandleStartDateChanged(DateTime newStartDate)
    {
        if (DateTime.Compare(newStartDate, EndDate) < 0)
        {
            StartDate = newStartDate;
            StartDateChanged.InvokeAsync(StartDate);
        }
        else
        {
            StateHasChanged();
        }
    }
    private void HandleEndDateChanged(DateTime newEndDate)
    {
        if (DateTime.Compare(StartDate, newEndDate) < 0)
        {
            EndDate = newEndDate;
            EndDateChanged.InvokeAsync(EndDate);
        }
        else
        {
            StateHasChanged();
        }
    }
}

要使用它,您可以这样做:

<EditForm Model=@TempModel>
    <DateTimePeriodComponent @bind-StartDate="DEBUG_START" @bind-EndDate="DEBUG_END" IsDisabled="IsDisabled" />
</EditForm>

我遇到的问题是,虽然在后端一切正常,这意味着如果开始日期晚于结束日期,则不会设置开始日期,但在 InputDate 中仍然显示错误的值。如果我在示例中切换 IsDisabled,则会显示正确的日期(例如上一个日期)。我怀疑这是由于 InputDate 不知何故没有更新,但我似乎无法弄清楚原因。据我所知,当您向绑定 Value=@StartDate 添加一个额外的 @ 时,它会启用双向绑定并且应该更改。

我是不是漏掉了一些愚蠢的东西,还是我只是做错了?

在我看来,您的控件应该在错误时使用可为空的日期和明确的值,可能是这样的:


    <div class="form-row">
        <div class="col">
            <label for="@($"startDate-{_id}")">Start datum</label>
            <InputDate class="form-control" id="@($"startDate-{_id}")" TValue="DateTime?" Value="@_StartDate" ValueChanged="@((e) => HandleStartDateChanged(e))" ValueExpression="(() => _StartDate)" />
        </div>
        <div class="col">
            <label for="@($"endDate-{_id}")">Eind datum</label>
            <InputDate class="form-control" id="@($"endDate-{_id}")" TValue="DateTime?" Value="@_EndDate" ValueChanged="@((e) => HandleEndDateChanged(e))" ValueExpression="(() => _EndDate)" />
        </div>
    </div>



@code{
    private string _id = Guid.NewGuid().ToString();

    [Parameter] public bool IsDisabled { get; set; }

    [Parameter] public DateTime StartDate { get; set; }
    [Parameter] public EventCallback<DateTime> StartDateChanged { get; set; }

    [Parameter] public DateTime EndDate { get; set; }
    [Parameter] public EventCallback<DateTime> EndDateChanged { get; set; }

    private DateTime? _StartDate { get; set; }
    private DateTime? _EndDate { get; set; }
    
    protected override void OnParametersSet()
    {
        _StartDate = StartDate;
        _EndDate = EndDate;
    }

    private void HandleStartDateChanged(DateTime? newStartDate)
    {
        if (newStartDate != null && newStartDate.Value != StartDate && newStartDate.Value < EndDate)
        {
            StartDate = newStartDate.Value;
            _StartDate = newStartDate;
            StartDateChanged.InvokeAsync(StartDate);
        }
        else
        {
            _EndDate = null;
            StateHasChanged();
        }
    }
    private void HandleEndDateChanged(DateTime? newEndDate)
    {
        if (newEndDate  != null && newEndDate.Value != EndDate &&  StartDate < newEndDate.Value )
        {
            EndDate = newEndDate.Value;
            _EndDate = newEndDate;
            EndDateChanged.InvokeAsync(EndDate);
        }
        else
        {
            _StartDate = null;
            StateHasChanged();
        }
    }
}

https://blazorfiddle.com/s/u0h87rmq

查看

此外,由于此组件位于 EditForm 内,您应该通知对 EditContext 的更改,检查