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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 03:32:02