两个jQuery DataTables - 尝试重新加载,显示/隐藏列等 - 对于其中一个DataTable而不是另一个

时间:2012-04-25 14:19:37

标签: javascript jquery ajax datatables

我在页面上有两个DataTables个对象,我们称之为searchResultsTable和currentPortfolioTable。当我点击按钮时,我正在使用fnReloadAjax插件按需重新加载DataTables。但是,只有其中一个表加载新数据(currentPortfolioTable),searchResultsTable会对数据执行ajax请求,但无法将新(和有效)数据加载到表中。

我试图破坏DataTable并创建一个新的,甚至重写了fnReloadAjax插件的一部分,看看我是否可以产生不同的结果。

即使只为currentPortfolioTable调用fnReloadAjax,它也拒绝显示加载的新数据。

使用DataTable的aoColumns属性的bVisible状态显示/隐藏列时,searchResultsTable无法加载新数据的问题也会出现。

示例代码:

var dataTableObjects = dataTableObjects || {
    "searchResultsTable": {},
    "currentPortfolioTable": {}
};

var _rankingsRootUrl = window.ROOT + 'rankings/';

var _defaultDataTableSettings = {
    "aoColumns": [
        {   "bSortable": false,
            "sTitle": "Add to Portfolio",
            "bVisible": true
        },
        {
            "bSortable": true,
            "sTitle": "Name of Investment",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "Chart",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "Rating",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "Minimum",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "ROR",
            "bVisible": false
        },
        {   "bSortable": true,
            "sTitle": "Max DD",
            "bVisible": false
        },
        {   "bSortable": true,
            "sTitle": "Sharpe",
            "bVisible": false
        },
        {   "bSortable": true,
            "sTitle": "Sterling",
            "bVisible": false
        }
    ],
    "aaSorting": [
    ],
    "sAjaxSource": _rankingsRootUrl + 'search_results/',
    "bServerSide": true,
    "bProcessing": true,
    "bPaginate": false,
    "bLengthChange": false,
    "sScrollY": 200,
    "sScrollX": "100%",
    "sScrollXInner": "100%",
    "bScrollCollapse": true,
    "fnServerData": function ( sSource, aoData, fnCallback ) {
        $.ajax( {
            "dataType": 'json',
            "type": "POST",
            "url": sSource,
            "data": aoData,
            "success": fnCallback
        } );
    },
    "fnServerParams": function ( aoData ) {
        aoData.push(
            {"name": "program_type", "value": $(':input#RankingProgramType').val()},
            {"name": "program_name", "value": $(':input#RankingProgramName').val()},
            {"name": "min_investment", "value": $(':input#RankingMinimumInvestment').val()},
            {"name": "rate_of_return", "value": $(':input#RankingRateOfReturn').val()},
            {"name": "max_dd", "value": $(':input#RankingMaxDd').val()},
            {"name": "time_span", "value": $(':input#RankingTimeSpan').val()},
            {"name": "flags", "value": $(':input#RankingFlags').val()},
            {"name": "strategies", "value": $(':input#RankingStrategies').val()},
            {"name": "recommended", "value": $(':input#RankingRecommended').val()},
            {"name": "portfolio_id", "value": (window.PORTFOLIO && window.PORTFOLIO.id) || ""}
        );
    }
};

var _defaultCurrentPortfolioTableSettings = {
    "aoColumns": [
        {
            "bSortable": true,
            "sTitle": "Name of Investment",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "Chart",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "Rating",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "Minimum",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "ROR",
            "bVisible": false
        },
        {   "bSortable": true,
            "sTitle": "Max DD",
            "bVisible": false
        },
        {   "bSortable": true,
            "sTitle": "Sharpe",
            "bVisible": false
        },
        {   "bSortable": true,
            "sTitle": "Sterling",
            "bVisible": false
        }
    ],
    "aaSorting": [
    ],
    "sAjaxSource": _rankingsRootUrl + 'current_portfolio/',
    "bServerSide": true,
    "bProcessing": true,
    "bPaginate": false,
    "bLengthChange": false,
    "sScrollY": 200,
    "sScrollX": "100%",
    "sScrollXInner": "100%",
    "bScrollCollapse": true,
    "fnServerData": function ( sSource, aoData, fnCallback ) {
        $.ajax( {
            "dataType": 'json',
            "type": "POST",
            "url": sSource,
            "data": aoData,
            "success": fnCallback
        } );
    },
    "fnServerParams": function ( aoData ) {
        aoData.push(
            {"name": "portfolio_id", "value": (window.PORTFOLIO && window.PORTFOLIO.id) || ""}
        );
    }
};

dataTableObjects.searchResultsTable = $('#search-results table').dataTable(_defaultDataTableSettings);
dataTableObjects.currentPortfolioTable = $('#currently-in-portfolio table').dataTable(_defaultCurrentPortfolioTableSettings);

$("#rankings").on("click", "a.add", function (e){
   dataTableObjects.searchResultsTable.fnReloadAjax('/datable1-url');
   dataTableObjects.currentPortfolioTable.fnReloadAjax('/datable2-url');
   e.preventDefault();
});

尝试修复:

  • 使用fnReloadAjax中的回调方法触发dataTable2数据的重新加载
  • 验证每个表的ID是否唯一
  • 验证dataTableJSObjects是页面的正确且唯一的表
  • 控制台记录没有错误或问题
  • JShinted js以确保没有js错误或错误
  • 关闭fnReloadAjax dataTableObjects.searchResultsTable和dataTableObjects.currentPortfolioTable仍然无法正确重新加载
  • 使用fnReloadAjax替换为fnDraw

4 个答案:

答案 0 :(得分:4)

感谢您发布额外的源代码详细信息。我想我可能已经找到了这个问题......

fnReloadAjax插件的说明中,Allan Jardine添加了以下注释:

  

注意:要在使用服务器端处理时重新加载数据,只需使用   内置API函数fnDraw而不是此插件。

现在,我意识到您已确认/datable1-url/datable2-url请求的数据是正确的,并且在使用fnReloadAjax时第一个数据表甚至正在正确重新加载;然而,根据艾伦的说明,由于问题的神秘性,缺乏更好的答案,我会说你当前实施的问题可能确实是由于fnReloadAjax不是适合您配置表格的方法。

我也意识到,只是简单地将fnReloadAjax更改为fnDraw,因为现在正在设置表格,这不会解决您的问题......时间变得棘手......

这是我的解决方案:

首先将这两行添加到脚本的顶部:

var isInitialLoadTable1 = true;
var isInitialLoadTable2 = true;

接下来,在每个dataTable设置变量中,在fnServerParams回调后添加以下附加回调:

"fnInitComplete": function( oSettings, json ) {
    isInitialLoadTable1 = false;
}

确保在第二个表格中将isInitialLoadTable1更改为initialLoadTable2 [并且不要忘记fnServerParams的结束括号后的逗号:-)]

现在为了狡猾......在fnServerData回调中更改了url来电的$.ajax设置,如下所示:

"url": (isInitialLoadTable1 ? sSource : '/datable1-url'),

同样,请确保在此声明中为第二个dataTable更改 2的

最后,将您的点击事件更改为以下内容:

$("#rankings").on("click", "a.add", function (e) {
    dataTableObjects.searchResultsTable.fnDraw();
    dataTableObjects.currentPortfolioTable.fnDraw();
    e.preventDefault();
});

现在,我还没有对此进行测试,但真正的测试取决于您的代码和数据。

希望这能解决问题。

答案 1 :(得分:2)

有一种想法是,在两个不同的表上连续调用fnReloadAjax可能会导致dataTable2发生冲突,如果它等待dataTable 1完成加载就不会遇到冲突。

fnReloadAjax函数接受一个可能有帮助的回调参数......

例如:

dataTableObjects.dataTable1 = $('#search-results table').dataTable();
dataTableObjects.dataTable2 = $('#currently-in-portfolio table').dataTable();

$("#rankings").on("click", "a.add", function (e){
    dataTableObjects.dataTable1.fnReloadAjax('/datable1-url', null, reloadDataTable2, false);
    e.preventDefault();
});

// outside of the "ready" block
var reloadDataTable2 = function () {
    dataTableObjects.dataTable2.fnReloadAjax('/datable2-url');
};

我没有对此进行过测试,因此我不确定它是否可行。

然而,我在寻找解决自己问题的方法时看到了这个问题,我想我会提出这个想法。希望这会有所帮助。

答案 2 :(得分:1)

我刚刚举了一个例子,表明它应该可以正常工作:http://live.datatables.net/aqazek/edit#javascript,html。我对fnReloadAjax做了一个微调,所以你可以看到重载对我的静态数据源的影响(只是用计数器重写一个单元格),但除此之外 - 没有来自DataTables站点的更改。

所以我想提供一些我们需要的进一步帮助,看看它不起作用的例子。

答案 3 :(得分:1)

针对此特定问题的解决方案是,为dataTableObjects.currentPortfolioTable返回的数据包含值sEcho,该值由DataTable用于数据分页,即,这是哪个数据页。可以在example usage of DataTables with Server Side Data中看到sEcho。

dataTableObjects.currentPortfolioTable的sEcho值始终设置为1,这显然导致DataTables始终认为数据仍然是原始数据集而不是新数据。将sEcho增加到新数据的AJAX请求中传回的值可以解决问题。