ASP.NET C#局部视图刷新后DataTable脚本异常求助
ASP.NET局部视图刷新后DataTable异常问题解决
问题现象
页面首次加载时所有功能正常,但刷新局部视图后,DataTable脚本无法正常运行并触发控制台报错,第三次刷新局部视图后脚本又恢复正常。
问题根源
- 局部视图每次加载都会执行
$('#example').DataTable({})初始化代码,第一次刷新后DOM中仍存在旧的DataTable实例,重复初始化会引发实例冲突报错。 - 第三次恢复属于偶然情况,并非稳定的修复状态。
解决方案
方案1:销毁旧实例后再初始化
修改局部视图中的脚本,先检查并销毁已存在的DataTable实例,再执行初始化:
$(function() { // 检查是否存在DataTable实例,存在则销毁 if ($.fn.DataTable.isDataTable('#example')) { $('#example').DataTable().destroy(); } // 重新初始化DataTable $('#example').DataTable({}); });
方案2:将初始化逻辑移到主视图AJAX回调中
移除局部视图中的DataTable初始化脚本,在主视图的AJAX成功回调中统一处理初始化,确保每次刷新后只执行一次初始化:
修改后的主视图脚本:
$(document).on('click', '#SearchButton', function() { try { $('#SearchButton').prop("disabled", true); var $form = $("#frmSearch"); var xModel = $form.serialize(); var Id = $('#Id').val(); var TaxCode = $('#TaxCode').val(); var Customer_SurName = $('#Customer_SurName').val(); var Customer_Name = $('#Customer_Name').val(); if (Id == "" && TaxCode == "" && Customer_SurName == "" && Customer_Name == "") { $('#SearchButton').prop("disabled", false); toastr.error('Please Fill any field to Search'); } else { $.ajax({ url: rootDir + 'Customers/Search', type: 'POST', dataType: 'html', cache: false, async: true, // 改为异步,避免阻塞UI data: xModel, success: function(data) { $('#SearchButton').prop("disabled", false); $("#PartialViewId").html(data); // 初始化DataTable前先销毁旧实例 if ($.fn.DataTable.isDataTable('#example')) { $('#example').DataTable().destroy(); } $('#example').DataTable({}); } }); } } catch (err) { $('#SearchButton').prop("disabled", false); Swal.fire({ icon: 'error', title: 'Oops...', text: err.message, }) } })
修改后的局部视图:
移除底部的<script type="text/javascript">$('#example').DataTable({});</script>代码块。
额外优化建议
- 移除
async: false:同步AJAX会阻塞浏览器UI,影响用户体验,改为异步更合理。 - 确保DataTable的CSS和JS资源仅在主视图加载一次:当前主视图已正确引入资源,无需在局部视图重复引入。
原代码参考
主视图代码
@using (Ajax.BeginForm("Search", "Customers", new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, UpdateTargetId = "PartialViewId" }, new { id = "frmSearch" })) { <div class="col-md-12 col-sm-12 col-xs-12"> <div class="x_panel"> <div class="x_title"> <h2>Search Clients</h2> <ul class="nav navbar-right panel_toolbox"> <li> <a class="collapse-link"> <i class="fa fa-chevron-up"></i> </a> </li> </ul> <div class="clearfix"></div> </div> <div class="x_content"> <div class="row"> <div class="col-md-6 col-sm-6 col-xs-12 "> <div class="form-group row"> @Html.Label("Customer Id", htmlAttributes: new { @class = "control-label col-md-3 col-xs-12 col-sm-3" }) <div class="col-sm-9 col-xs-12 col-md-9"> @Html.TextBoxFor(model => model.Id, "Enter Surname", new { @class = "form-control required", Id = "Id" }) </div> </div> </div> <div class="col-md-6 col-sm-6 col-xs-12 "> <div class="form-group row"> @Html.LabelFor(model => model.TaxCode, htmlAttributes: new { @class = "control-label col-md-3 col-xs-12 col-sm-3" }) <div class="col-sm-9 col-xs-12 col-md-9"> @Html.TextBoxFor(model => model.TaxCode, "Enter Name", new { @class = "form-control required", Id = "TaxCode" }) </div> </div> </div> </div> <div class="row"> <div class="col-md-6 col-sm-6 col-xs-12 "> <div class="form-group row"> @Html.LabelFor(model => model.Customer_SurName, htmlAttributes: new { @class = "control-label col-md-3 col-xs-12 col-sm-3" }) <div class="col-sm-9 col-xs-12 col-md-9"> @Html.TextBoxFor(model => model.Customer_SurName, "Enter Surname", new { @class = "form-control required", Id = "Customer_SurName" }) </div> </div> </div> <div class="col-md-6 col-sm-6 col-xs-12 "> <div class="form-group row"> @Html.LabelFor(model => model.Customer_Name, htmlAttributes: new { @class = "control-label col-md-3 col-xs-12 col-sm-3" }) <div class="col-sm-9 col-xs-12 col-md-9"> @Html.TextBoxFor(model => model.Customer_Name, "Enter Name", new { @class = "form-control required", Id = "Customer_Name" }) </div> </div> </div> </div> </div> <button id="SearchButton" type="button" class="btn btn-success">Search</button> </div> </div> } <div id="PartialViewId"> @{ Html.RenderPartial("_SearchResults"); } </div> <script src="//cdn.jsdelivr.net/npm/sweetalert2@11"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js"></script> <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.12.1/css/jquery.dataTables.css"> <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.12.1/js/jquery.dataTables.js"></script> <script type="text/javascript"> //Root Directory for java script Path Configuration var rootDir = "@Url.Content("~/"))"; $(document).on('click', '#SearchButton', function() { try { $('#SearchButton').prop("disabled", true); var $form = $("#frmSearch"); var xModel = $form.serialize(); var Id = $('#Id').val(); var TaxCode = $('#TaxCode').val(); var Customer_SurName = $('#Customer_SurName').val(); var Customer_Name = $('#Customer_Name').val(); if (Id == "" && TaxCode == "" && Customer_SurName == "" && Customer_Name == "") { $('#SearchButton').prop("disabled", false); toastr.error('Please Fill any field to Search'); } else { $.ajax({ url: rootDir + 'Customers/Search', type: 'POST', dataType: 'html', cache: false, async: false, data: xModel, success: function(data) { $('#SearchButton').prop("disabled", false); $("#PartialViewId").html(data); } }); } } catch (err) { $('#SearchButton').prop("disabled", false); Swal.fire({ icon: 'error', title: 'Oops...', text: err.message, }) } }) </script>
局部视图代码
@if (Model != null) { <div class="col-md-12 col-sm-12 col-xs-12"> <div class="x_panel"> <div class="x_title"> <h2>Search Results</h2> <ul class="nav navbar-right panel_toolbox"> <li> <a></a> </li> <li> <a class="collapse-link"> <i class="fa fa-chevron-up"></i> </a> </li> </ul> <div class="clearfix"></div> </div> <p> <a href="@Url.Action(" Create", "Customers" )" class="btn btn-success fa fa-plus"> Create New</a> </p> <div class="table-responsive"> @if (Model != null) { <table id="example" class="display"> <thead> <tr> <th>Surname</th> <th>Customer Name</th> <th>Contact Number</th> <th>Date of Birth</th> <th>Birth Place</th> <th></th> </tr> </thead> <tbody> @foreach (var item in Model.OrderBy(x => x.Id)) { <tr class="even pointer"> <td>@item.Customer_SurName</td> <td>@item.Customer_Name</td> <td>@item.Contact_Number</td> <td>@item.Date_of_Formated </td> <td>@item.Birth_Place</td> <td> @Html.ActionLink(" Edit Customer", "Edit", new { id = item.Id }, new { @class = "btn btn-primary pull-right fa fa-pencil", @target = "_blank" }) @Html.ActionLink(" View Tasks", "Details", new { id = item.Id }, new { @class = "btn btn-dark pull-right fa fa-eye", @target = "_blank" }) @Html.ActionLink(" Create Task", "Create", "TaskMains", new { id = MondoData.Models.IdEncrypt.Encrypt(item.Id.ToString()) }, new { @class = "btn btn-success pull-right fa fa-plus" }) </td> </tr> } </tbody> </table> } </div> </div> </div> } <script type="text/javascript"> $('#example').DataTable({}); </script>
内容的提问来源于stack exchange,提问作者Sandun_909
相关产品推荐
相关产品推荐

