ASP.NET Core:如何通过专科下拉框筛选医生列表?
解决医生专科筛选功能的实现方案
核心问题分析
现有代码存在3个关键问题导致筛选失效:
- 视图下拉框绑定的
SelectedSpecialty属性,与控制器接收的参数specialty名称不匹配,导致筛选参数无法正确传递 - 缺少触发筛选的交互机制(提交按钮/自动提交事件)
- 空的
filterList函数未实现筛选逻辑
下面提供两种实现方案,可根据需求选择:
方案1:服务器端整页刷新(简单快速)
步骤1:完善ViewModel
确保DoctorIndexViewModel包含接收选中值的属性:
public class DoctorIndexViewModel { public List<Doctor> Doctors { get; set; } public List<SelectListItem> SpecialtyListItems { get; set; } // 新增:接收下拉框选中的专科值 public string SelectedSpecialty { get; set; } }
步骤2:修改控制器参数与逻辑
将控制器参数与ViewModel属性名统一,并回传选中状态:
[HttpGet] public async Task<IActionResult> Index(string selectedSpecialty) { List<Doctor> doctors; List<string> specialties = await doctorRepository.GetSpecialties(); if (!string.IsNullOrWhiteSpace(selectedSpecialty)) { doctors = await context.Doctors .Include(d => d.User) .Where(d => d.Specialty == selectedSpecialty) .ToListAsync(); } else { doctors = await context.Doctors .Include(d => d.User) .ToListAsync(); } var doctorViewModel = new DoctorIndexViewModel { Doctors = doctors, SpecialtyListItems = specialties .Distinct() .OrderBy(s => s) .Select(s => new SelectListItem { Text = s, Value = s }) .ToList(), // 回传选中值,保持下拉框选中状态 SelectedSpecialty = selectedSpecialty }; return View(doctorViewModel); }
步骤3:修改视图添加表单与触发逻辑
用表单包裹下拉框,添加提交按钮或自动提交事件:
@model planMyMDVisit.Models.ViewModels.DoctorIndexViewModel <h2>In-Network Doctors</h2> <h6>Filter doctors by specialty:</h6> <!-- 表单提交到Index方法 --> <form asp-action="Index" method="get"> <select asp-for="SelectedSpecialty" asp-items="Model.SpecialtyListItems" id="list" class="form-control" onchange="this.form.submit()"> <!-- 移除disabled,设置空值以支持显示所有医生 --> <option value="">-- SELECT SPECIALTY--</option> </select> <!-- 可选:添加手动提交按钮 --> <button type="submit" class="btn btn-primary mt-2">筛选</button> </form> <!-- 医生列表,添加空状态提示 --> @if(Model.Doctors.Any()) { @foreach(var hct in Model.Doctors.GroupBy(d => d.Specialty).OrderBy(d => d.Key)) { <h4>@hct.Key</h4> @foreach (var doctor in hct.OrderBy(d => d.Name)) { <div> <i>@doctor.Specialty</i> <strong> <a href="@Url.Action("Show", "Doctors", new { id = doctor.Id })">@doctor.Name</a> </strong> </div> } } } else { <p>没有找到对应专科的医生</p> }
方案2:客户端AJAX无刷新(体验更优)
步骤1:同方案1的ViewModel与控制器修改
额外给控制器添加返回部分视图的逻辑:
[HttpGet] public async Task<IActionResult> Index(string selectedSpecialty, bool isPartial = false) { List<Doctor> doctors; List<string> specialties = await doctorRepository.GetSpecialties(); if (!string.IsNullOrWhiteSpace(selectedSpecialty)) { doctors = await context.Doctors .Include(d => d.User) .Where(d => d.Specialty == selectedSpecialty) .ToListAsync(); } else { doctors = await context.Doctors .Include(d => d.User) .ToListAsync(); } // AJAX请求时返回仅包含医生列表的部分视图 if (isPartial) { return PartialView("_DoctorListPartial", doctors); } var doctorViewModel = new DoctorIndexViewModel { Doctors = doctors, SpecialtyListItems = specialties .Distinct() .OrderBy(s => s) .Select(s => new SelectListItem { Text = s, Value = s }) .ToList(), SelectedSpecialty = selectedSpecialty }; return View(doctorViewModel); }
步骤2:创建医生列表部分视图_DoctorListPartial.cshtml
@model List<planMyMDVisit.Models.Doctor> @if(Model.Any()) { @foreach(var hct in Model.GroupBy(d => d.Specialty).OrderBy(d => d.Key)) { <h4>@hct.Key</h4> @foreach (var doctor in hct.OrderBy(d => d.Name)) { <div> <i>@doctor.Specialty</i> <strong> <a href="@Url.Action("Show", "Doctors", new { id = doctor.Id })">@doctor.Name</a> </strong> </div> } } } else { <p>没有找到对应专科的医生</p> }
步骤3:修改主视图添加AJAX逻辑
@model planMyMDVisit.Models.ViewModels.DoctorIndexViewModel <h2>In-Network Doctors</h2> <h6>Filter doctors by specialty:</h6> <select asp-for="SelectedSpecialty" asp-items="Model.SpecialtyListItems" id="list" class="form-control"> <option value="">-- SELECT SPECIALTY--</option> </select> <button type="button" id="filterBtn" class="btn btn-primary mt-2">筛选</button> <!-- 医生列表容器,加载部分视图 --> <div id="doctorListContainer"> @await Html.PartialAsync("_DoctorListPartial", Model.Doctors) </div> <script> // 绑定筛选按钮点击事件 document.getElementById('filterBtn').addEventListener('click', filterList); // 可选:绑定下拉框变更事件自动筛选 document.getElementById('list').addEventListener('change', filterList); async function filterList() { const selectedSpecialty = document.getElementById('list').value; // 发起AJAX请求获取筛选后的列表片段 const response = await fetch(`@Url.Action("Index", "Doctors")?selectedSpecialty=${encodeURIComponent(selectedSpecialty)}&isPartial=true`); if (response.ok) { const html = await response.text(); document.getElementById('doctorListContainer').innerHTML = html; } else { alert('筛选失败,请重试'); } } </script>
内容的提问来源于stack exchange,提问作者bradd
相关产品推荐
相关产品推荐

