jQuery动态DataTables重新加载

3
在我的Laravel应用程序中,我有多个页面都有DataTables,它们都有"class = mydttable"的类。我使用Ajax将数据加载到DataTables中。 在每个表的每一行中,我都有一个带有删除按钮的列。每当我按下它时,我会对相应的行执行删除操作,然后我想重新加载数据到datatable中。我可以通过if语句来判断哪个表格上有按钮,然后执行这个重载操作,但是我想知道是否有更简单的方法来实现这个重载操作。 更具体地说... 在我的custom.js文件中,我像下面这样填充dataTable:
var uzTable = $('#users').DataTable( {
                "processing": true,
                "serverSide": true,
                "sAjaxSource": "sspXController?draw=1",
...
});

var cliTable = $('#clients').DataTable( {
                "processing": true,
                "serverSide": true,
                "sAjaxSource": "sspXController2?draw=1",
...
});

var marTable = $('#market').DataTable( {
                "processing": true,
                "serverSide": true,
                "sAjaxSource": "sspXController3?draw=1",
...
});

现在,处理删除按钮的点击事件,在执行删除操作后需要进行重新加载

$( document ).on('click', '.ssDelete', function(e){
                e.preventDefault();
                $.ajax({
                    url:    someFormAction,
                    type:   'POST',
                    dataType: 'html',
                    success:function(data) {
                        $(".mydttable").ajax.reload();
                    }

});

我的 HTML 大致如下:

<table id="users" class="row-border hover order-column table mydttable dataTable no-footer" cellspacing="0" width="100%">
                            <thead>
                                <tr role="row">
                                   <th class="small-sorting" style="width:84px"></th>
                                   <th class="small-sorting" style="width:84px">Operatiuni</th>
                                </tr>
                            </thead>
                            <tbody>
                                <tr>
                                    <td></td>
                                    <td></td>
                                </tr>
                            </tbody>            
                        </table>

当然,上面的HTML只是第一个DataTable(“users”)的HTML代码,其他表格也有HTML代码,但我不会在这里粘贴它,以避免让这个问题过长。此外,在任何给定时间,视图(html)中只显示一个dataTable
所以,当我点击具有ssDelete ID的任何按钮时,我会删除当前显示的dataTable的当前记录,并且我想要刷新包含删除按钮的dataTable。由于我没有为每个表单独立编写删除函数,因此我也希望能够更简洁地完成ajax重新加载等操作。
因此,我的目标是能够在单击“#ssDelete”按钮时重新加载文档中加载的任何DataTable,而无需进行额外的分配和条件语句...但我的尝试并没有起作用:
 success:function(data) {
     $(".mydttable").ajax.reload(); // NOT WORKING
 ... 

我该怎样做呢? 编辑 人们似乎没有读完我的问题,所以我在这里重复一下关键点: 我需要能够仅有一个函数来删除多个数据表中的记录。为了达到这个目的(删除部分已经完成且正常工作),我需要刷新/重新加载可见数据表的内容。而且我需要这样做而不必测试哪个表是可见的。 基于所有我的数据表都共享同一个类的事实,我应该能够调用一个通用的数据表,并对其应用ajax.reload()函数。但这并不起作用。我需要一种访问当前视图中任何数据表的通用方法...类似于:
$(".mydttable").ajax.reload();

或者

$('.mydttable').dataTable().fnReloadAjax();

或者

$('.mydttable').DataTable().ajax.reload();

显然,如果我这样做,jQuery会尝试在普通的Table元素上执行一个函数,而不是在Table的dataTable转换上执行。如果我像上面那样尝试将DataTable()应用于元素,则会出现:

未捕获的TypeError:无法读取未定义的“重新加载”属性

以下是我的Ajax调用(也不起作用):

                var idtable = $('.mydttable').attr('id');
                $.ajax({
                    url:    myFormAction,
                    type:   'POST',
                    cache:  false,
                    data : { _token: csrf_token, _method:'DELETE' },
                    dataType: 'html',
                    success:function(data) {
                        $('#DeleteModalDialog').modal('hide');
                        if(idtable=='users'){
                            alert('uzerii');
                            uzTable.ajax.reload();
                        }else if(idtable=='clients'){
                            alert('Clients');
                            cliTable.ajax.reload();
                        }else if(idtable=='market'){
                            alert('Market');
                            marTable.ajax.reload();
                        }
                    }
                });

即使我收到警报,它也知道可见表的ID(uzTable、cliTable和marTable是如上所述的jquery变量),重载不会发生。

我的代码有什么问题?我该怎么解决?

1个回答

2

你需要使用服务器端处理。这里是我如何处理的一个例子。

$('.dtable').DataTable({
  /*
   * Shows message dialog of loading data for slow connections
   */
  processing: true,
  /*
   * Does an ajax call to get the data
   * Happens every time you search or sort
   */
  serverSide: true,
  /*
   * full_numbers = first, last, next, previous, and numbers
   * in the pagation
   */
  pagingType: "full_numbers",
  /*l = show X entries
   * f = search box
   * <> = div
   * <"class" = class name
   * t = table
   * r = 'proccessing' dialog
   * i = 10 out of 1000 records
   * p = pagation
   * */
  dom: 'lf<"nstuff"p><"toolbar">trip',
  /*
   * Defines the ajax call
   */
  ajax: {
    url: 'url.php',
    datatype: "json",
    type: "post",
    /*Adds data to ajax call*/
    data: function(d) {
      d.action = 'list';
    }
  },
  /*Defines columns*/
  columns: [
    /* Everything in here is sent to server upon ajax call.
     * Orderable false = no arrows to order by
     * searchable false = doesn't search that column
     * */
    {
      title: "name",
      render: function() {
        /*
         * arguments[2] is the third parameter passed in through the
         * function. it holds the entire row data in it.
         */
        var row = arguments[2];
        return "<a href='?" + row.id + "'>" + row.name + "</a>";
      }
    }, {
      title: "Info",
      "orderable": false,
      render: function() {
        return arguments[2].email;
      }
    }, {
      title: "Action",
      data: 'id',
      "orderable": false
    }
  ],
  /*Orders from this to that*/
  order: [
    [0, 'asc']
  ]
});
<?php
function list($REQUEST) {
        /*
         * Draw is returned back to datatables in order for javascript to not render
         * Older draws first in case of async ajax calls.
         */
        $draw = $this->aspam($REQUEST, true, 'draw');
        /* Query Handles the search field in the datatables plugin */
        $query = $this->aspam($this->aspam($REQUEST, false, 'search'), false, 'value');
        /* Data holds the extra variables */
        $data = $this->aspam($REQUEST, false, 'data');
        /* This is the array of order from datatables */
        $order = $this->aspam($REQUEST, false, 'order');
        /* Where to start the limit */
        $start = $this->aspam($REQUEST, true, 'start');
        /* how long the limit is */
        $length = $this->aspam($REQUEST, true, 'length');
        /* Set up all the variables defaults to not throw errors */
        $orderby = '';
        $where = '';
        $first = TRUE;
        /* if order is array itterate through it and set the order */
        if (is_array($order)) {
            foreach ($order as $o) {
                if ($first) {
                    $first = FALSE;
                } else {
                    $orderby .= ',';
                }
                /* 0 = Name
                 * $o[dir] is either asc or desc based on datatables
                 */
                switch ($o['column']) {
                    case 0:
                    case '0':
                        $orderby .= "entity_name $o[dir]";
                        break;
                }
            }
            /* if not empty create the order by */
            if (!empty($orderby)) {
                $orderby = "ORDER BY $orderby";
            }
        }
        /* if the search string is not empty search all the searchable fields */
        if (!empty($query)) {
            $where .= "
                AND (
                    name like '%$query%'
                )";
        }

        /* This is the selection query 
         * It creates the sql with out and with the where
         */

        $sql_nowhere = ($sql = "
            select from where
        ");
        $sql_somewhere = ($sql .= "
                $where
        ");
        $sql .= "
                $orderby
                LIMIT $start,$length
        ";
        /*
         * after all the where and join clauses are created get the filtered
         * count of all the records
         */
        $recordsFiltered = $this->getCounts($sql_somewhere);
        /* The total amount of records in this call */
        $recordsTotal = $this->getCounts($sql_nowhere);
        if (!$temp = $this->retrieve($sql)) {
            /* if no results are shown create $temp as an empty array to not through errors */
            $temp = [];
        }
        /* creates the datatables array that it likes so it won't through an error */
        $array = array(
            'draw' => $draw
            , 'recordsTotal' => $recordsTotal
            , 'recordsFiltered' => $recordsFiltered
            , 'data' => $temp
        );
        return $array;
    }

    /**
     * gets the total count of sql
     * @param type $sql
     * @return type
     */
    function getCounts($sql) {
        return $this->retrieve("SELECT count(*) as count FROM ($sql) as z")[0]['count'];
    }

除此之外,我建议使用按钮上的点击事件来触发删除操作。

$('button').click(function() {
  var id = $(this).data('id');
  deleteMe(id).done(function() {
    $('dtable').reload();
  });
});

function deleteMe(id) {
  /*code for what ever you do with the id.*/
  return $.ajax();
}
<button data-id="555">
  Me
</button>

这个脚本并不能立即帮助你,但它会指引你朝着正确的方向前进。 编辑

var tables = [];
var options = [{
  ajax: 1
}, {
  ajax: 2
}, {
  ajax: 3
}, {
  ajax: 4
}, ];
$('dtable').each(function(index) {
  $(this).data('id', index);
  tables.push($(this).DataTables(options[index]));
});
$(document).on('click', '.ssDelete', function(e) {
  var index = $(this).closest('dtable').data('id');
  e.preventDefault();
  $.ajax({
    url: someFormAction,
    type: 'POST',
    dataType: 'html',
    success: function(data) {
      tables[index].ajax.reload();
    }
  });
});
<table class='dtable'></table>
<table class='dtable'></table>
<table class='dtable'></table>
<table class='dtable'></table>

每次使用datatables时,它都会返回datatable句柄。您需要使用该句柄才能刷新表格。我提供了一种添加多个表格的方法,而不需要大量冗余代码。只需确保您的options.lengthdtable.length相同即可。否则,您将抛出索引越界错误。

非常感谢你提供如此详细的答案,但你没有回答我的实际问题。我已经在Ajax中使用了服务器端处理,并获取了我的dataTable的数据。我的问题是,我在项目中至少有5个dataTables(全部使用服务器端处理ajax加载),我想为所有的dataTables使用相同的删除jquery函数。因此,除了使用IF-ELSE-IF进行检查之外,我需要以某种方式来识别这些dataTables(通过类)。这就是我的问题所在。 - user1137313
你可以通过抓取某种类型的DOM元素来遍历哪个按钮被按下了。在事件内部,你可以获取$(this)元素并遍历查找所需的函数。 - Roger
好的。正如您在问题中所看到的,我正在做这件事。但它并不像那样工作。可能是因为我得到的是一个TABLE元素,而不是DATATABLE元素。所以我似乎无法抓取一个Table元素并将ajax.reload()应用于它。它就是不像那样工作。请尝试自己操作,这样您就可以理解我在说什么了。您似乎已经有了一个类似的项目。只需尝试使用具有Table-DataTable元素的2个HTML,并使用相同的custom.js文件,在其中放置一个处理两个datatables的删除函数。我不确定如何更好地解释。 - user1137313
好的,忘记了处理程序。当您使用datatables时,它会返回您用于刷新表格的处理程序。 - Roger
没错。所以我需要一种访问可见表格处理程序并告诉它重新加载页面的方法。有什么想法吗?请查看我的问题的编辑部分。 - user1137313

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接