我结合了这个页面上的几个解决方案,以及其他解决方案,在 JSFiddle 中构建了一个简单的演示 - 演示 $log 服务的使用,使用装饰器对其进行增强以添加行号($log 调用所在的行号制成)。我还在 Plunker 中做了一个更全面的解决方案,演示了 $log 服务的使用,使用装饰器对其进行了增强,以添加行号、调用者文件名和实例名。希望这对其他人有用。
JSFiddle 网址 - https://jsfiddle.net/abhatia/6qnz0frh/
这个小提琴已经用以下浏览器测试过:
- IE 11 - (JSFiddle Javascript 的第一行编号是 72)。
- Firefox 46.0.1 -(JSFiddle Javascript 的第一行编号是 72)。
- Chrome 50.0.2661.94 m -(JSFiddle Javscript 的第一行编号为 71)。
结果很好。但是,请注意 Chrome 中的行号与 FF 或 IE 相比会减 1,即因为 JSFiddle 的 javascript 代码的第一行号在 FF/IE 和 Chrome 之间有所不同,如上所示。
Plunker URL - https://embed.plnkr.co/YcfJ7V/
这个plunk很好地展示了这个概念,有详细的解释,并且还提供了带有Angular官方默认$log服务示例的控制台输出,因此可以将两者进行对比。 Plunk 也已经在上面列出的浏览器上进行了测试。
下面的屏幕截图是上面 Plunk 示例的控制台输出。有 3 个突出显示的区域:
- 红框显示使用默认 $log 服务的控制台输出。从控制器调用的 $log 函数。
- 蓝色框显示使用扩展 $log 服务的控制台输出。从控制器调用的 $log 函数。您可以看到脚本名称和行号的显示方式,以及控制器名称(在实例化 $log 时使用)。
- 橙色框对比默认控制台输出和扩展 $log 服务。
当您查看 Plunk 代码时,这一点会变得非常清楚。
这里是 JSFiddle 中使用的 getLineNumber 函数(略微增强的版本使用 Plunker 示例返回调用者文件名):
function getLineNumber(newErr, sliceIndex1, sliceIndex2)
{
var lineNumber = -1;
var lineLocation;
var stack = newErr.stack.split('\n').slice(2);
if (navigator.userAgent.indexOf("Chrome") > -1) {
stack.shift();
}
stack = stack.slice(sliceIndex1, sliceIndex2);
var stackInString = stack + '';
var splitStack;
if (navigator.userAgent.indexOf("Chrome") > -1) {
splitStack = stackInString.split(" ");
}
else {
splitStack = stackInString.split("@");
}
lineLocation = splitStack[splitStack.length - 1];
//console.log(lineLocation);
lineNumber = lineLocation.split(":")[2];
return lineNumber;
}