MVC应用如何无需二次查询数据库即可在客户端查看广告详情
实现思路
你已经将全量广告数据一次性传递到前端视图,只需要把数据提前持久化到前端内存/元素属性中,点击时直接读取前端缓存的数据渲染详情即可,完全不需要发起后端请求,自然不会触发二次数据库查询。
下面提供两种可直接落地的实现方案:
方案1:全局变量缓存全量数据(推荐,数据量大时性能更好)
该方案全局仅序列化一次全量数据,适合广告总条数多、单条数据字段丰富的场景
步骤1:序列化全量广告数据到前端JS变量
在你的视图顶部添加如下代码,把Model转成JSON字符串存到全局变量:
@using System.Text.Json <!-- 全局缓存所有广告数据 --> <script> const allAds = @Html.Raw(JsonSerializer.Serialize(Model, new JsonSerializerOptions { PropertyNamingPolicy = null })); </script>
步骤2:给广告行绑定ID标识和点击事件
修改你的循环渲染代码,给每条广告的行添加自定义data-ad-id属性和点击触发方法,同时补充详情弹窗的基础结构:
@model IEnumerable<CarbonSmartsolution.Models.Ad> <!-- 详情弹窗HTML,默认隐藏 --> <div id="adDetailModal" style="display:none; position:fixed; top:50%; left:50%; transform:translate(-50%,-50%); padding:20px; background:#fff; border:1px solid #eee; z-index:999;"> <h3 id="detailTitle"></h3> <p id="detailDesc"></p> <!-- 其他需要展示的详情字段按需补充 --> <button onclick="document.getElementById('adDetailModal').style.display='none'">关闭</button> </div> @foreach (var item in Model) { <!-- 给标题行加点击事件和广告ID属性 --> <tr class="border-bottom-0 bg-transparent" data-ad-id="@item.Id" onclick="showAdDetail(this)"> <td class="border-bottom-0"> @Html.DisplayFor(modelItem => item.Title) </td> </tr> <tr> <td> @Html.DisplayFor(modelItem => item.desciption) </td> </tr> }
步骤3:实现点击展示详情的JS方法
function showAdDetail(el) { // 读取点击行的广告ID const adId = parseInt(el.dataset.adId); // 从全局缓存中匹配对应广告数据 const targetAd = allAds.find(ad => ad.Id === adId); if(!targetAd) return; // 填充数据到详情弹窗 document.getElementById('detailTitle').innerText = targetAd.Title; document.getElementById('detailDesc').innerText = targetAd.desciption; // 其他字段按需填充 // 显示弹窗 document.getElementById('adDetailModal').style.display = 'block'; }
方案2:元素属性挂载单条数据(适合轻量场景)
该方案代码更简洁,不需要维护全局变量,适合单条广告字段少、总数据量小的场景
直接把单条广告的完整数据序列化后存到点击元素的data属性里,点击时直接读取:
@foreach (var item in Model) { <tr class="border-bottom-0 bg-transparent" data-ad-detail="@Html.Raw(JsonSerializer.Serialize(item))" onclick="showAdDetail(this)"> <td class="border-bottom-0"> @Html.DisplayFor(modelItem => item.Title) </td> </tr> <tr> <td> @Html.DisplayFor(modelItem => item.desciption) </td> </tr> }
对应的JS方法修改为:
function showAdDetail(el) { // 直接读取元素上挂载的广告详情 const targetAd = JSON.parse(el.dataset.adDetail); // 后续填充弹窗逻辑和方案1一致 document.getElementById('detailTitle').innerText = targetAd.Title; document.getElementById('detailDesc').innerText = targetAd.desciption; document.getElementById('adDetailModal').style.display = 'block'; }
内容的提问来源于stack exchange,提问作者YacineSM
相关产品推荐
相关产品推荐

