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

ASP.NET Core点击下拉标签动态加载磁盘文件的实现问题

实现ASP.NET Core下拉菜单的文件懒加载方案

我明白你的需求——要把下拉菜单的文件列表改成懒加载,只有用户点击「Consulter les conventions」的时候才去加载磁盘文件并生成菜单,而不是页面一开始就全部加载。之前加onclick没生效还报函数未定义,大概率是脚本加载时机或者作用域的问题,咱们一步步来解决:

1. 调整前端下拉菜单结构

先把初始的下拉菜单设为空(或放加载提示),保留Bootstrap的下拉标记,但先不渲染菜单项:

<div class="dropdown">
  <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="conventionsDropdownBtn">Consulter les conventions</a>
  <div class="dropdown-menu" id="conventionsMenuContainer">
    <!-- 初始显示加载提示 -->
    <span class="dropdown-item-text px-3">Chargement...</span>
  </div>
</div>

2. 编写前端懒加载脚本

用原生JS绑定点击事件,确保脚本在DOM渲染完成后执行(避免找不到元素或函数未定义的问题):

document.addEventListener('DOMContentLoaded', function() {
  const dropdownBtn = document.getElementById('conventionsDropdownBtn');
  const menuContainer = document.getElementById('conventionsMenuContainer');
  let hasLoadedFiles = false; // 标记是否已加载,避免重复请求

  dropdownBtn.addEventListener('click', async function(e) {
    // 已加载过就直接展开下拉,不再请求
    if (hasLoadedFiles) return;

    e.preventDefault(); // 阻止默认跳转行为
    menuContainer.innerHTML = '<span class="dropdown-item-text px-3">Chargement...</span>';

    try {
      // 调用后端API获取文件列表
      const response = await fetch('/api/Files/GetConventions');
      if (!response.ok) throw new Error('Échec du chargement des fichiers');
      
      const fileList = await response.json();
      menuContainer.innerHTML = ''; // 清空加载提示

      // 遍历生成下拉菜单项
      fileList.forEach(file => {
        const link = document.createElement('a');
        link.className = 'dropdown-item';
        link.href = `/Files/Download?fileName=${encodeURIComponent(file.FileName)}`;
        link.textContent = file.DisplayName || file.FileName;
        menuContainer.appendChild(link);
      });

      hasLoadedFiles = true;
      // 手动触发Bootstrap下拉展开(如果用了Bootstrap)
      if (typeof $ !== 'undefined') {
        $(dropdownBtn).dropdown('toggle');
      } else {
        // 原生方式展开下拉(不用jQuery)
        dropdownBtn.parentElement.classList.add('show');
        menuContainer.classList.add('show');
      }
    } catch (err) {
      menuContainer.innerHTML = `<span class="dropdown-item-text px-3 text-danger">Erreur : ${err.message}</span>`;
      console.error(err);
    }
  });
});

3. 后端编写文件列表API

在ASP.NET Core中创建一个API控制器,用来读取磁盘文件并返回数据:

[ApiController]
[Route("api/[controller]")]
public class FilesController : ControllerBase
{
    private readonly IWebHostEnvironment _webHostEnv;

    public FilesController(IWebHostEnvironment webHostEnv)
    {
        _webHostEnv = webHostEnv;
    }

    // 获取约定文件列表的API
    [HttpGet("GetConventions")]
    public IActionResult GetConventionFiles()
    {
        // 替换为你实际的文件存储路径(比如wwwroot下的Conventions文件夹)
        var fileDir = Path.Combine(_webHostEnv.WebRootPath, "Conventions");
        
        if (!Directory.Exists(fileDir))
        {
            return Ok(new List<FileInfoDto>()); // 目录不存在返回空列表
        }

        var files = Directory.GetFiles(fileDir)
            .Select(path => new FileInfoDto
            {
                FileName = Path.GetFileName(path),
                DisplayName = Path.GetFileNameWithoutExtension(path) // 可自定义显示名称
            })
            .ToList();

        return Ok(files);
    }

    // 文件下载接口
    [HttpGet("/Files/Download")]
    public IActionResult DownloadFile(string fileName)
    {
        var filePath = Path.Combine(_webHostEnv.WebRootPath, "Conventions", fileName);
        if (!System.IO.File.Exists(filePath))
        {
            return NotFound();
        }

        var stream = new FileStream(filePath, FileMode.Open);
        return File(stream, "application/octet-stream", fileName);
    }

    // 用于传递文件信息的DTO
    public class FileInfoDto
    {
        public string FileName { get; set; }
        public string DisplayName { get; set; }
    }
}

为什么之前的onclick无效?

你遇到的「函数未定义」问题,通常是这两个原因:

  • 函数定义在局部作用域(比如DOMContentLoaded回调内),全局访问不到;
  • 脚本加载在元素之前,绑定事件时元素还未渲染。

用addEventListener绑定事件的方式更可靠,能确保元素存在后再绑定逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 18:27:46