Blazor InputFile 重置/清除值 - statehaschanged() 不起作用

MSu*_*row 5 subcomponent blazor

我有一个使用 Blazor InputFile 组件作为子组件的组件。

当我选择一个文件时,按预期调用 OnChange 处理程序。但是,如果我两次选择同一个文件,则不会再次调用 OnChange 处理程序(我猜这符合预期,因为选择没有改变,但是我的用例需要这个)。

因此,我想如果我可以选择一个文件并调用 OnChange 处理程序并在 OnChange 处理程序中“重置”所选文件,那么即使再次选择了相同的文件,我也应该获得对处理程序的新调用。

我不知道如何重置 InputFile(子)组件中的文件选择。调用this.StateHasChanged()处理程序不会导致 InputFile 组件重新呈现。

如果没有 JSInterop 并手动将 DOM 输入元素的值字段设置为“”,这是否可行(这是否可行)?

我的组件:

@using stuff;

<div class="drag-drop-area">
    Drag and drop file here
    <InputFile OnChange="@OnInputFileChange"></InputFile>
</div>

@code {

    [Parameter]
    public String SomeParam { get; set; } = "";

    private async Task OnInputFileChange(InputFileChangeEventArgs e) {
        // do stuff with file

        // do _something_ here to reset InputFile

        this.StateHasChanged(); //<-- this doesn't cause InputFile re-render
    }
Run Code Online (Sandbox Code Playgroud)

到目前为止,我尝试这样做包括:

  • 遵循与此相关的各种提示/技巧。StateHasChanged(),即
    • await Task.Delay(1);
    • await InvokeAsync(StateHasChanged);
  • 将值添加到 InputFileAdditionalAttributes.Add(..)以查看是否可以强制重新渲染
  • 查看使用 RenderFragment 动态添加 InputFile 组件,但是在代码中创建 InputFile 的新实例时我无法传递 OnChanged 参数(处理程序),这意味着我不会使用 InputFileChangeEventArgs 进行回调
  • 查看将 InputFile 包装在 EditForm 中以重置表单(Blazor EditForms 显然没有重置功能?)
  • [编辑] OnInputFileChange 同时使用 Task 和 void

小智 19

您可以将 @key 添加到 InputFile 并在处理 OnChange 事件时更改它,而不是调用 StateHasChanged 两次:

<InputFile @key=@(_inputFileId) OnChange="@LoadFiles" multiple />

@code {
    private string _inputFileId = Guid.NewGuid().ToString();
    
    private Task LoadFiles(InputFileChangeEventArgs e)
    {
        // load file here

        // the InputFile maintains the file the user has chosen and will ignore importing same file, i.e. you can't import the same file more than once to the inputfile control
        // to fix this the InputFile component key is changed so that blazor sees it as a new component and re-creates it in the browser DOM thereby clearing its state (and the file property of it)
        _inputFileId = Guid.NewGuid().ToString();

        return Task.CompletedTask;
    }

}```
Run Code Online (Sandbox Code Playgroud)

  • 更简洁的解决方案和更清晰的意图 (2认同)
  • 这是有效的,因为更改“@key”的值将强制生成_new_ html 元素。 (2认同)

Dan*_*man 3

仍然不是一个很好的解决方案 - 但更简洁一点并且有效:

将 InputFile 包裹在布尔值中以临时隐藏/显示。这会清除该值。

@if (!bClearInputFile)
{
    <InputFile class="form-control-file" OnChange="@OnInputFileChange" />
}

@code
{
    //Call ClearInputFile whenever value must be cleared.
    private void ClearInputFile()
    {
        bClearInputFile = true;
        StateHasChanged();
        bClearInputFile = false;
        StateHasChanged();
    }
}
Run Code Online (Sandbox Code Playgroud)