正确禁止显示数据表中的警告

Correctly Suppressing Warnings in DataTables?

本文关键字:警告 数据表 禁止显示      更新时间:2023-09-26

我正在尝试正确抑制数据表中的警告(警报)。DataTables 的标准行为是在发生错误时抛出 javascript 警报;但是,这目前对我来说很不方便。我一直在尝试通过以下方式将警告转换为 javascript 错误

$.fn.dataTableExt.sErrMode = 'throw';

这工作正常,但这会停止当前的 javascript 执行,这不是我想要的。因此,我将 DataTables 操作(初始化和更改)包装在一个没有错误处理的 try-catch 中;但是,这也会停止 JavaScript 的执行。(在Chrome和Firefox上测试)

我的问题是我如何摆脱这些错误/警报以进行调试?我正在尝试调试脚本的其他部分,但这些警报不断妨碍。

我使用此关闭函数修改了本机警报,以将数据表警告重定向到控制台。

window.alert = (function() {
    var nativeAlert = window.alert;
    return function(message) {
        window.alert = nativeAlert;
        message.indexOf("DataTables warning") === 0 ?
            console.warn(message) :
            nativeAlert(message);
    }
})();

它会在第一次触发时将window.alert还原到其本机函数。如果不希望它还原到原始警报,只需注释掉window.alert = nativeAlert;行即可。

注意:这个答案适用于dataTables 1.9.x!

对于$.fn.dataTableExt.sErrMode来说,唯一重要的值是"警报"。它是"警觉"或其他任何东西。 sErrMode由内部调度程序函数_fnLog处理,在 v1.9.2 中关于 media/js/jquery.dataTables.js 中的第 4575 行:

function _fnLog( oSettings, iLevel, sMesg )
{
    var sAlert = (oSettings===null) ?
        "DataTables warning: "+sMesg :
        "DataTables warning (table id = '"+oSettings.sTableId+"'): "+sMesg;
    if ( iLevel === 0 )
    {
        if ( DataTable.ext.sErrMode == 'alert' )
        {
            alert( sAlert );
        }
        else
        {
            throw new Error(sAlert);
        }
        return;
    }
    else if ( window.console && console.log )
    {
        console.log( sAlert );
    }
}

不幸的是,没有办法覆盖dataTables内部函数,相信我 - 我已经尝试过,不可能使用原型或其他任何东西。你可以在这里阅读作者Allan Jardines自己的评论:

我很遗憾地说,由于数据表是如何在 时刻,无法使用 Javascript 在 DataTables 范围之外。这将是 每当我开始做 2.x 系列时解决(这可能会 休息一会儿!- 但目前你需要改变核心。

有人可能会认为:嘿,也许iLevel标志可以在设置中的某个地方更改?再次,不幸的是没有。 iLevel在对_fnLog的每个内部调用中都进行了硬编码。

令人失望的是,我们必须在丑陋的警报和完全停止执行之间做出选择,因为会抛出错误。简单地覆盖window.onerror也不起作用。解决方案是修改_fnLog,只需注释掉抛出自定义错误的行:

else
{
  // throw new Error(sAlert); <-- comment this line
}

如果您有$.fn.dataTableExt.sErrMode = 'throw'(除"警报"以外的任何其他内容)并且发生错误,则执行将继续。更好的是,在其他情况下可能需要那些抛出的错误,在外面设置一个标志,比如

window.isDebugging = true;

else
{
  if (!window.isDebugging) throw new Error(sAlert); 
}

在我看来,这不是一个"黑客",而是推翻了有时不令人满意的一般不可避免的jQuery dataTables行为。正如Allan Jardine本人在上面的链接中所写:

为什么不能只修改源?这就是开放的全部意义 来源 :-)

这里有一个解决方案,它略有修改,可以在 v1.10.2 中工作,而无需更改任何供应商文件:

$.fn.dataTableExt.sErrMode = "console";
$.fn.dataTableExt.oApi._fnLog = function (oSettings, iLevel, sMesg, tn) {
  var sAlert = (oSettings === null)
    ? "DataTables warning: "+sMesg
    : "DataTables warning (table id = '"+oSettings.sTableId+"'): "+sMesg
  ;
  if (tn) {
    sAlert += ". For more information about this error, please see "+
              "http://datatables.net/tn/"+tn
    ;
  }
  if (iLevel === 0) {
    if ($.fn.dataTableExt.sErrMode == "alert") {
      alert(sAlert);
    } else if ($.fn.dataTableExt.sErrMode == "thow") {
      throw sAlert;
    } else  if ($.fn.dataTableExt.sErrMode == "console") {
      console.log(sAlert);
    } else  if ($.fn.dataTableExt.sErrMode == "mute") {}
    return;
  } else if (console !== undefined && console.log) {
    console.log(sAlert);
  }
}

DataTables 版本 1.10.15 开始,您可以将 $.fn.dataTableExt.errMode 设置为 "ignore",它将静默忽略错误消息:

    $(document).ready(function () {
        $.fn.dataTableExt.errMode = 'ignore';
    });

_fnLog数据表函数具有以下代码:

        if ( type == 'alert' ) {
            alert( msg );
        }
        else if ( type == 'throw' ) {
            throw new Error(msg);
        }
        else if ( typeof type == 'function' ) {
            type( settings, tn, msg );
        }

默认值为"警报",这是有问题的。

您也可以设置为"投掷"。它将创建javascript错误,但不会打扰用户。

"忽略"或任何其他值只会简单地跳过错误。

试试这个:

$.fn.DataTable.ext.oApi._fnLog = function (settings, level, msg, tn) {
    msg = 'DataTables warning: ' +
            (settings !== null ? 'table id=' + settings.sTableId + ' - ' : '') + msg;
    if (tn) {
        msg += '. For more information about this error, please see ' +
                'http://datatables.net/tn/' + tn;
    }
    console.log( msg );
};

让我在上面大卫康拉德的回答中加上我的 2 美分。在不更改文件的情况下修改_fnLog函数的一种方法是从数据表设置中的 Api 实例获取对该方法的引用:

$.fn.dataTableSettings[0].oApi._fnLog = function(settings, level, msg, tn) {
    // Modified version of _fnLog
}

希望这对某人有所帮助。