Blazor中能否不挂载到DOM,动态创建文件选择输入组件?
需求:实现点击按钮触发文件选择并处理文件
想要实现的效果等同于以下JavaScript代码:点击按钮后动态创建文件输入框并触发选择,完成后提示所选文件名。
document.querySelector("button").addEventListener("click", () => { const input = document.createElement("input"); input.type = "file"; input.onchange = () => alert("You picked: " + input.files[0]?.name); input.click(); });
<button>Pick File</button>
尝试的方案(失败)
尝试动态创建InputFile组件,但无法获取组件引用(Id和Context均为null):
Blazor页面代码
<div class="text-center mt-5"> <button class="btn btn-primary" @onclick="@this.AddFiles"> @("AddFiles".Loc()) </button> </div>
C#逻辑代码
async Task AddFiles() { var input = new InputFile(); await this.Js.InvokeVoidAsync("triggerClick", input.Element); // triggerClick 是触发元素点击的JavaScript方法 }
当前临时方案(实现复杂)
目前采用挂载隐藏InputFile到DOM中的方式实现,但步骤繁琐:
Blazor页面代码
@inject IJSRuntime Js; <div class="text-center mt-5"> <button class="btn btn-primary" @onclick="this.AddFiles"> @("AddFiles".Loc()) </button> </div> @if (this.fileRequested) { <InputFile @ref="this.txtFile" OnChange="this.OnFileChanged" class="d-none" /> }
C#逻辑代码
bool fileRequested = false; InputFile? txtFile; protected override async Task OnAfterRenderAsync(bool firstRender) { if (this.fileRequested && this.txtFile is not null) { await this.Js.InvokeVoidAsync("triggerClick", this.txtFile.Element); } } async Task AddFiles() { this.fileRequested = true; } async Task OnFileChanged(InputFileChangeEventArgs e) { this.fileRequested = false; await this.Js.InvokeVoidAsync("alert", "You picked: " + e.File?.Name); }
内容的提问来源于stack exchange,提问作者Luke Vo
相关产品推荐
相关产品推荐

