如何使用MVC中的ajax从服务器重新初始化dataTables

时间:2015-03-19 16:52:05

标签: jquery ajax asp.net-mvc datatables

所以这里我有管理员的菜单列表,在我们的下面我有上传新闻。单击此特定菜单时,我将调用部分视图,如下所示。

$("#body_data").load("/Admin/GetDailyNews", function () {
          $("#dailyNews").dataTable({
                    "lengthMenu": [[5, 10, 25, 50, -1], [5, 10, 25, 50, "All"]],
                    "columnDefs": [{ "targets": 3, "orderable": false }],
                    "pagingType": "full_numbers",
                    "oLanguage": { "sSearch": "" },
                    "deferRender": true
          });
}

AdminController中的我的PartialViewResult如下:

[HttpGet]
public PartialViewResult GetDailyNews()
{
     var context=new MyContext();
     List<AVmodel.NewsEventsViewModel> model = new List<AVmodel.NewsEventsViewModel>();
     List<news> news = (from n in context.news where n.stdate >= System.DateTime.Now orderby n.stdate descending select n).ToList();
     foreach (var NEWS in news)
     {
          model.Add(new AVmodel.NewsEventsViewModel()
          {
               EDate = NEWS.stdate,
               EDesc = NEWS.brief,
               EName = Convert.ToString(NEWS.name),
               NID = NEWS.nid
          });
     }
     return PartialView("_UploadNews", model);
}

我的_UploadNews.cshtml如下

@model IEnumerable<MCB.Models.BusinessObjects.AVmodel.NewsEventsViewModel>
<table id="dailyNews" cellspacing="0" width="100%" class="table table-condensed table-hover table-responsive table-bordered order-column">
     <thead>
           <tr>
               <th>Event Date</th>
               <th>Event Name</th>
               <th>Detailed News</th>
               <th class="disabled">Actions</th>
          </tr>
     </thead>
     <tbody>
          @foreach (var news in Model)
          {
               <tr data-row="row_@news.NID">
                   <td>@news.EDate.Date.ToShortDateString()</td>
                   <td>@Convert.ToString(news.EName)</td>
                   <td>@Convert.ToString(news.EDesc)</td>
                   <td><button class="btn btn-primary" data-target="#editAddNews" data-toggle="modal" onclick="javascript: EditNews(this);" data-info="data_@news.NID"><span class="fa fa-edit"></span> </button>&nbsp; <button class="btn btn-danger" onclick="javascript: DeleteNews(this);" data-info="data_@news.NID"><span class="fa fa-trash-o"></span></button></td>
               </tr>
          }
     </tbody>
</table>

所以到现在为止它还不错。一切进展顺利,桌子只显示未来几天的新闻。现在我可以选择管理员从表中获取整套新闻,包括过去几天。所以我在部分视图中保留了一个复选框,如下所示引导开关类型

<input type="checkbox" name="fetchNews-checkbox" data-on-text="All News" data-off-text="Upcoming News" data-on-color="primary" data-off-color="default" data-label-width="100px" data-label-text="News details">

我为该特定复选框写了一个onswitchchange,如下所示:

$("[name='fetchNews-checkbox']").on('switchChange.bootstrapSwitch', function (event, state) {
     if (state) 
     {
           fetchNews('all');
     }
     else 
     {
           fetchNews('upcoming');
     }
});

我的fetchNews功能如下:

function fetchNews(context)
{
    if(context!="")
    {
        $("#dailyNews").dataTable({
            "sPaginationType": "full_numbers",
            "bProcessing": true,
            "bServerSide": true,
            "sAjaxSource": "/Admin/FetchNews"
        });
    }
}

调用此函数时,我收到一条警告

  

DataTables警告:table id = dailyNews - 无法重新初始化   数据表。有关此错误的详细信息,请参阅   http://datatables.net/tn/3

我访问了上述链接,但无法理解任何内容。任何人都可以让我知道,如何调用控制器json方法并将新闻列表呈现到此表中?

8 个答案:

答案 0 :(得分:56)

错误消息http://datatables.net/tn/3准确地说明了问题。您正在使用fetchNews()中的不同选项重新初始化表格。

您需要先破坏表格,请参阅http://datatables.net/manual/tech-notes/3#destroy。 您可以使用$("#dailyNews").dataTable().fnDestroy()(DataTables 1.9.x)或$("#dailyNews").DataTable().destroy()(DataTables 1.10.x)执行此操作。

function fetchNews(context)
{
     if(context!="")
     {
        // Destroy the table
        // Use $("#dailyNews").DataTable().destroy() for DataTables 1.10.x
        $("#dailyNews").dataTable().fnDestroy()

        $("#dailyNews").dataTable({
           // ... skipped ...
        });
    }
}

或者,如果您使用的是DataTables 1.10.x,则可以使用其他选项"destroy": true初始化新表,请参阅下文。

function fetchNews(context)
{
     if(context!="")
     {
        $("#dailyNews").dataTable({
            "destroy": true,
            // ... skipped ...
        });
    }
}

答案 1 :(得分:36)

经过大量研究后,这对我有用: - 首先检查dataTable是否存在, 如果确实销毁了dataTable然后重新创建它

&#13;
&#13;
if ($.fn.DataTable.isDataTable("#mytable")) {
  $('#mytable').DataTable().clear().destroy();
}

$("#mytable").dataTable({...
                       
                });
&#13;
&#13;
&#13;

答案 2 :(得分:1)

数据表具有检索选项。如果您的表格在初始化后收到其他内容,则可以设置参数:retrieve:true,

您可以在此处查看文档:{​​{3}}

$("#body_data").load("/Admin/GetDailyNews", function () {
      $("#dailyNews").dataTable({
                retrieve: true,
                "lengthMenu": [[5, 10, 25, 50, -1], [5, 10, 25, 50, "All"]],
                "columnDefs": [{ "targets": 3, "orderable": false }],
                "pagingType": "full_numbers",
                "oLanguage": { "sSearch": "" },
                "deferRender": true
      });

}

答案 3 :(得分:1)

虽然以上答案可以解决症状(“无法重新初始化” 警告),但它们不能解决问题的根本原因:您不得从内部填充DataTable jQuery $.load() / $.ajax() / $.get() / $.post()成功回调,因为它引发了由异步AJAX调用性质引起的各种问题。

通过调用DataTables .destroy()方法,您可以使情况变得更糟,因为每次从服务器检索数据时,都不必要破坏并创建新的DataTable,这至少会浪费性能。 >

相反,您应该使用DataTables ajax选项,该选项在需要的地方和时间触发AJAX调用,使您可以充分利用DataTables API方法而不会降低性能,例如,要重新获取数据,您只需执行ajax.reload(),如果您需要在加载最新数据之前更改URL,请执行ajax.url().load()

OP示例的完整实时演示 DEMO 看起来很简单:

//initialize DataTables
const dataTable = $('#newsTable').DataTable({
	//specify AJAX source, params and response source
	ajax: {
		url: 'https://newsapi.org/v2/everything',
		data: () => ({
				q: ($('input[name="subject"]:checked').val() || 'javascript'),
				language: 'en',
				apiKey: '699ba21673cd45aba406b1984b480b60'
		}),
		dataSrc: 'articles'
	},
	//set up table columns
	columns: [
		{title: 'Source', data: 'source.name'},
		{title: 'Title', data: 'title'},
		{title: 'Content', data: 'content'}
	]
});

//trigger table data re-fetch with new subject
$('input[name="subject"]').on('change', () => dataTable.ajax.reload())
<!doctype html>
<html>
<head>
  <script type="application/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
  <script type="application/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
  <script type="application/javascript" src="test.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
</head>
<body>
  <label>Pick the subject:</label>
  <input type="radio" name="subject" value="python">python</input>
  <input type="radio" name="subject" value="javascript">javascript</input>
  <table id="newsTable"></table>
</body>
</html>

答案 4 :(得分:0)

$('#mytable').DataTable().destroy(); $('#mytable').html('');

答案 5 :(得分:0)

经过大量研究,这对我有用: $('#userList')。DataTable()。clear()。destroy();

答案 6 :(得分:0)

我可以每次通过提供destroy属性来重新初始化数据表,如下所示:

            .done(function(ret){
                $("#cloud").DataTable({
                   ordering : true,
                   pageLength : 20,
                   destroy: true,
                   data : loadData(ret)
                })
            });

答案 7 :(得分:0)

这将使用新内容重新加载数据表。

$("#dailyNews").dataTable().ajax.reload();