我在chrome中使用angularjs $ log,但它显示的行如:angular.js:9037,我想显示我调用此方法的行号。(显示我的js名称和正确的行),是谁知道呢?或角度没有此功能。
答案 0 :(得分:16)
在Chrome中,有一项名为Blackboxing的功能。 您可以使用它从调试会话或开发工作流中排除/绕过(库)源。
因此,如果您使用blackbox angular,则会绕过$ log服务的内部,并且控制台会打印正确的行号!
答案 1 :(得分:3)
您可以通过将装饰器应用于$log
服务来访问它:
module.config(function logConfig($provide, $logProvider) {
$provide.decorator('$log', function ($delegate) {
var originalFns = {};
// Store the original log functions
angular.forEach($delegate, function (originalFunction, functionName) {
originalFns[functionName] = originalFunction;
});
var functionsToDecorate = ['debug', 'warn'];
// Apply the decorations
angular.forEach(functionsToDecorate, function (functionName) {
$delegate[functionName] = logDecorator(originalFns[functionName]);
});
return $delegate;
});
function logDecorator(fn) {
return function () {
var args = [].slice.call(arguments);
// Insert a separator between the existing log message(s) and what we're adding.
args.push(' - ');
// Use (instance of Error)'s stack to get the current line.
var stack = (new Error()).stack.split('\n').slice(1);
// Throw away the first item because it is the `$log.fn()` function,
// but we want the code that called `$log.fn()`.
stack.shift();
// We only want the top line, thanks.
stack = stack.slice(1, 2);
// Put it on the args stack.
args.push(stack);
// Call the original function with the new args.
fn.apply(fn, args);
};
}
});
我这是一个可包含的模块,但我相信它也可以在应用程序.config()
内完成。
我通过在线粘合多个不同来源构建了这个(以及一些额外的逻辑);我通常非常擅长保留对它们的引用,但我想我在构建它时并没有这么做,所以不幸的是我无法引用我的灵感。如果有人回复,我会把它放在这里。
注1: 这是我实际使用的略微简化的版本,所以你必须仔细检查
logDecorator()
的堆栈 狡猾的魔法虽然它应该如所呈现的那样有效。注意B:
Error.prototype.stack
{{1}}是非标准的(需要IE10,可能在许多移动浏览器上不受支持),因此您可能希望通过类似MDN says的内容来扩充它以获取堆栈本身
答案 2 :(得分:2)
我已经结合了这个页面的几个解决方案,以及其他人在JSFiddle中构建一个简单的演示 - 演示使用$ log服务,用装饰器增强它来添加行号(来自$ log调用的行号)制作)。我还在Plunker中做了一个稍微全面的解决方案,演示了使用$ log服务,用装饰器增强它来添加行号,调用者文件名和实例名。希望这对其他人有用。
JSFiddle网址 - https://jsfiddle.net/abhatia/6qnz0frh/
这个小提琴已经过以下浏览器的测试:
结果很好。但请注意,与FF或IE相比,Chrome中的行号将减1,即因为JSFiddle的javascript代码第一行号在FF / IE和Chrome之间有所不同,如上所列。
Plunker网址 - https://embed.plnkr.co/YcfJ7V/
这个插件很好地演示了这个概念,详细解释并且还提供了Angular的默认$ log服务的官方示例的控制台输出,因此这两者可以进行对比。 Plunk也已经过上面列出的浏览器测试过。
下面的屏幕截图是上面Plunk示例中的控制台输出。有三个突出的领域:
当您查看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;
}
答案 3 :(得分:1)
行号来自运行时。一般情况下你不能设置它。
但并非所有人都失去了。在行号非常重要的地方,您可以使用不同的呼叫。
记得注入$window
然后注入:
$window.console.log("test1");
你通过格式化,跨浏览器填充代码等方式放弃了一些东西,但是你确实可以免费获得正确的行号,而不需要每个运行时特定的代码。
答案 4 :(得分:1)
接近floatingLomas's回答
module.config(function($logProvider, $provide){
$provide.decorator('$log', function ($delegate) {
$delegate.info = function () {
var args = [].slice.call(arguments);
if (window.console && window.console.table)
console.trace(args[0], args[1]);
else
$delegate.log(null, args)
};
return $delegate;
});
})
通常第二个@行是你需要的,在这种情况下是90618
答案 5 :(得分:1)
我使用了floatLomas解决方案并进行了一些调整,因为它在FF上不起作用,堆栈略有不同。像IE这样的幻像不支持Error.stack并且爆炸。 日志位置可以在chrome中单击,但不能在ff中单击。
app.config(function logConfig($provide, $logProvider) {
$provide.decorator('$log', function ($delegate) {
var originalFns = {};
// Store the original log functions
angular.forEach($delegate, function (originalFunction, functionName) {
originalFns[functionName] = originalFunction;
});
var functionsToDecorate = ['debug', 'warn'];
// Apply the decorations
angular.forEach(functionsToDecorate, function (functionName) {
$delegate[functionName] = logDecorator(originalFns[functionName]);
});
return $delegate;
});
function logDecorator(fn) {
return function () {
var args = [].slice.call(arguments);
// Insert a separator between the existing log message(s) and what we're adding.
args.push(' - ');
// Use (instance of Error)'s stack to get the current line.
var newErr = new Error();
// phantomjs does not support Error.stack and falls over so we will skip it
if (typeof newErr.stack !== 'undefined') {
var stack = newErr.stack.split('\n').slice(1);
if (navigator.userAgent.indexOf("Chrome") > -1) {
stack.shift();
}
stack = stack.slice(0, 1);
var stackInString = stack + '';
var splitStack;
if (navigator.userAgent.indexOf("Chrome") > -1) {
splitStack = stackInString.split(" ");
} else {
splitStack = stackInString.split("@");
}
var lineLocation = splitStack[splitStack.length - 1];
// Put it on the args stack.
args.push(lineLocation);
// Call the original function with the new args.
fn.apply(fn, args);
}
};
}
答案 6 :(得分:0)