如何在 Blazor 中更改日期输入值

How to change date input value on change in Blazor

我试图将日期输入中的 selected 日期强制为用户实际 selected 日期的星期日。所以如果他们选择星期三,它实际上会变成同一周的星期日。

我已经设法做到了,但是当我再次select同一周的约会时,它不起作用。例如,当用户 select 是星期三时,它成功地 select 是星期日。但是当他们去 select 星期二时,它会将显示值保留为星期二而不是将其更改为星期日(这是我希望它做的)

这是一些示例代码

<input type="date" value="@overrideStart.ToString("yyyy-MM-dd")" @onchange="@SelectStartOfWeek" />

@code {
    private DateTime overrideStart = DateTime.Today;

    protected override async Task OnInitializedAsync()
    {
        overrideStart = GetStartOfWeek(overrideStart)
    }

    public async Task SelectStartOfWeek(ChangeEventArgs args)
    {
        var value = args.Value.ToString();
        overrideStart = value == string.Empty ? DateTime.Today : DateTime.Parse(value);

        overrideStart = await GetStartOfWeek(overrideStart);
    }
    private async Task<DateTime> GetStartOfWeek(DateTime date)
    {
        return date.AddDays(-(int)date.DayOfWeek);
    }
}

显然问题是因为它认识到 overrideStartSelectStartOfWeek 完成后以相同的值结束。我已经试过了StateHasChanged(),但似乎没有任何效果。

您已正确识别问题,但我认为只有一些 hacky 方法可以避免这种优化。

其中一种方法是更改​​元素上的其他内容,例如 @key,这将强制 Blazor 替换整个元素。

<input 
    @key="@toggle"
    type="date" 
    value="@overrideStart.ToString("yyyy-MM-dd")" 
    @onchange="@SelectStartOfWeek" />

@code {
    bool toggle;
    private DateTime overrideStart = DateTime.Today;

    protected override async Task OnInitializedAsync()
    {        
        overrideStart = await GetStartOfWeek(overrideStart);
    }

    public async Task SelectStartOfWeek(ChangeEventArgs args)
    {
        var value = args.Value.ToString();
        overrideStart = value == string.Empty ? DateTime.Today : DateTime.Parse(value);

        overrideStart = await GetStartOfWeek(overrideStart);
        toggle = !toggle;

    }
    private ValueTask<DateTime> GetStartOfWeek(DateTime date)
    {
        return ValueTask.FromResult(date.AddDays(-(int)date.DayOfWeek));
    }
}

在 属性 上使用 setter 的另一种方法。这可以独立工作,并且 EditForm 上下文。

@page "/MyDate"
<h3>MyDate Editor</h3>
<EditForm EditContext="editContext">
    <InputDate @bind-Value="model.MyDate"></InputDate>
</EditForm>
<input type="date" @bind-value="this.MyDate" />

@code {

    private dataModel model { get; set; } = new dataModel();
    private EditContext editContext;

    protected override Task OnInitializedAsync()
    {
        this.editContext = new EditContext(model);
        return base.OnInitializedAsync();
    }


    public class dataModel
    {
        public DateTime? MyDate
        {
            get => _myDate;
            set
            {
                if (value != null)
                {
                    var date = (DateTime)value;
                    _myDate = date.AddDays(-(int)date.DayOfWeek);
                }
            }
        }
        private DateTime? _myDate;
    }

    public DateTime? MyDate
    {
        get => _myDate;
        set
        {
            if (value != null)
            {
                var date = (DateTime)value;
                _myDate = date.AddDays(-(int)date.DayOfWeek);
            }
        }
    }
    private DateTime? _myDate;
}