You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core MVC模态弹窗局部视图JavaScript失效问题求助

问题:ASP.NET Core 10 MVC模态弹窗中局部视图的JavaScript无法正常运行

开发环境

  • ASP.NET Core 10 MVC Web App

问题场景

模态弹窗加载的文件选择器局部视图(_FileUploadPartialView)渲染完成后,绑定的文件选择事件JavaScript代码无法触发。


局部视图代码(_FileUploadPartialView.cshtml)

<div id="dropArea">
    <form asp-controller="ArtPieces" asp-action="UploadFiles" enctype="multipart/form-data">
        <input name="file" type="file" accept="image/*">
        <button type="submit" name="btnIncoming" >Upload File</button>
        <input type="hidden" asp-for="SourceFileName" id="sourceFile" />
        <input name="existSrcName" asp-for="SourceFileName" type="hidden" />
    </form>
</div>

父视图代码

@model UploadFileVM
<form id="aspFormFileData" asp-action="Edit">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <input type="hidden" asp-for="ID" />
    <div class="row" >
        <div class="form-group col">
            <label asp-for="FileData.SourceName" class="control-label">@Model.FileData?.SourceName</label>
        </div>
        <div class="form-group col">
            <button type="button" class="btn btn-secondary" id="btnFileSource">Choose File...</button>
        </div>
    </div>
</form>
<div class="modal" role="dialog" tabindex="-1" id="filePicker">
    <div class="modal-header">
        <button type="button" class="close" style="position: absolute; top: 0; right: 0;" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">&times;</span>
        </button>
        <h5>@selectFileViewModel.SourceName </h5>
        <h3 id="fileGetModal" class="modal-title">Get a file to upload</h3>
    </div>
    <div class="modal-body" id="testModal">
    </div>
</div>

绑定事件的JavaScript代码

const submitButton = document.querySelector('button[name="btnIncoming"]');
document.addEventListener('DOMContentLoaded', () =>
{
    const fileInput = document.getElementById('input[name="file"]');
        fileInput.addEventListener('change', () => { handleInputChanged() });
});

function handleInputChanged() {
    alert("Input changed");
    try {
        assertFilesValid(fileInput.files);
    } catch (err) {
        updateStatusMessage(err.message);
        return;
    }
    submitButton.removeAttribute('disabled');
}

已尝试的方案及问题

  • 已知局部视图无法使用@section Scripts {},将JS代码移至父视图或_Layout后,因局部视图元素未加载,addEventListener因找不到元素报错;
  • 添加元素存在的条件判断后,JS仍无法触发;
  • 尝试基于IHtmlContent的HTML Helper方案,以及用IHttpContextAccessor替代废弃IHtmlString的方案,均未解决,且@Html引用不支持新结构实现。

解决方案

方法1:使用事件委托(推荐)

利用事件冒泡机制,将事件绑定到已存在的父元素(如document或模态弹窗容器),动态加载的元素触发事件时仍能被捕获。修改JS代码如下:

// 绑定到document,监听name为file的输入框的change事件
document.addEventListener('change', function(e) {
    if (e.target.name === 'file') {
        handleInputChanged(e.target);
    }
});

const submitButton = document.querySelector('button[name="btnIncoming"]');

function handleInputChanged(fileInput) {
    alert("Input changed");
    try {
        assertFilesValid(fileInput.files);
    } catch (err) {
        updateStatusMessage(err.message);
        return;
    }
    submitButton?.removeAttribute('disabled');
}

方法2:局部视图加载完成后手动绑定事件

在加载局部视图的回调(如AJAX请求完成、模态弹窗显示后)中,手动执行事件绑定。假设通过AJAX加载局部视图到testModal:

// 点击选择文件按钮加载局部视图并绑定事件
document.getElementById('btnFileSource').addEventListener('click', function() {
    fetch('/ArtPieces/FileUploadPartialView') // 替换为你的局部视图Action路径
        .then(response => response.text())
        .then(html => {
            document.getElementById('testModal').innerHTML = html;
            // 加载完成后绑定事件
            const fileInput = document.querySelector('#testModal input[name="file"]');
            fileInput.addEventListener('change', () => handleInputChanged(fileInput));
        });
    // 显示模态框(若使用Bootstrap模态框)
    $('#filePicker').modal('show');
});

const submitButton = document.querySelector('button[name="btnIncoming"]');

function handleInputChanged(fileInput) {
    alert("Input changed");
    try {
        assertFilesValid(fileInput.files);
    } catch (err) {
        updateStatusMessage(err.message);
        return;
    }
    submitButton?.removeAttribute('disabled');
}

方法3:将脚本嵌入局部视图(不推荐但可行)

直接在局部视图末尾添加<script>标签,局部视图加载时脚本会自动执行。需注意若模态框多次打开,可能导致脚本重复加载:

<div id="dropArea">
    <form asp-controller="ArtPieces" asp-action="UploadFiles" enctype="multipart/form-data">
        <input name="file" type="file" accept="image/*">
        <button type="submit" name="btnIncoming" >Upload File</button>
        <input type="hidden" asp-for="SourceFileName" id="sourceFile" />
        <input name="existSrcName" asp-for="SourceFileName" type="hidden" />
    </form>
</div>

<script>
    const submitButton = document.querySelector('button[name="btnIncoming"]');
    const fileInput = document.querySelector('#dropArea input[name="file"]');
    fileInput.addEventListener('change', handleInputChanged);

    function handleInputChanged() {
        alert("Input changed");
        try {
            assertFilesValid(fileInput.files);
        } catch (err) {
            updateStatusMessage(err.message);
            return;
        }
        submitButton.removeAttribute('disabled');
    }
</script>

内容的提问来源于stack exchange,提问作者DigAtRandom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 20:08:10