2

当我使用 angular $log 服务时,控制台中的所有行都会显示对 angular.js:5687 的引用,而不是我调用 $log.log 函数的行。

如何获得对我调用 $log 的行的引用?此外,我有自己的服务,它围绕 $log,我如何引用对我的服务的调用而不是 $log?

例如在Logger.js中:

 1) angular.module('MyApp').factory('Logger', function($log){
 2)    return { log : function(msg) { $log.log(msg); };
 3) });

SomeCtrl.js中

 1) angular.module('MyApp').controller('SomeCtrl', function($scope, $log, Logger) {
 ...
10) $log.log('Hi from $log');     // reference to SomeCtrl.js:10
 ...
25) Logger.log('Hi from Logger'); // reference to SomeCtrl.js:25
4

2 回答 2

1

由于我假设您仅在开发中登录,并且与大多数开发人员一样,您在 Chrome 中进行开发,因此您可以将属性添加到全局范围,如下所示:

通过访问 V8 JavaScript (Chrome & Node.js) 中的行号

Object.defineProperty(window, '__stack', {
  get: function(){
    var orig = Error.prepareStackTrace;
    Error.prepareStackTrace = function(_, stack){ return stack; };
    var err = new Error;
    Error.captureStackTrace(err, arguments.callee);
    var stack = err.stack;
    Error.prepareStackTrace = orig;
    return stack;
  }
});

Object.defineProperty(window, '__line', {
  get: function(){
    return __stack[1].getLineNumber();
  }
});

console.log(__line);

现在您可以__line在代码中的任何位置使用。

编辑:看起来您无法从调用堆栈中获取文件名。如果您正在编写干净的 JavaScript,则每个文件都应该有自己的范围,您可以在其中定义var filename = 'test.js';,因此您可以如下所示:

在某处全局定义:

Object.defineProperty(window, '__prevLine', {
    get: function () {
        console.log('__line', __stack);
        return __stack[2].getLineNumber();
    }
});

function log(s) {
    console.log(s, __prevLine)
}

你的实现:

(function () {
    var _scriptName = 'test.js';

    // ... lots of code

    log('something happened', _scriptName);
}());

这是一个演示这个想法的小提琴:

http://jsfiddle.net/langdonx/zJJ8r/

于 2013-04-30T13:49:27.743 回答
1

感谢@Langdon 为我指明了正确的方向。

[注意]此解决方案仅适用于Chrome。有关更多信息,请查看:

这是我实施的解决方法:

Object.defineProperty(window, '__stack', {
  get : function() {
     var orig = Error.prepareStackTrace;
     Error.prepareStackTrace = function(_, stack) {
        return stack;
     };
     var err = new Error;
     Error.captureStackTrace(err, arguments.callee);
     var stack = err.stack;
     Error.prepareStackTrace = orig;
     return stack;
  }
});

Logger.log = function(msg) {
  var stack = __stack;
  var link = stack[1].getFileName() + ':' + stack[1].getLineNumber();
  console.groupCollapsed("%c" + msg, "font-weight: normal;");
  $log.log(link); // or console.log(link) if you're not using angular.
  console.groupEnd();
};

[注意]在 chrome 开发工具控制台中,我不知道如何覆盖右侧给出的链接。我一直在寻找有关此的文档,但我没有找到任何东西。如果您知道,请告诉我,因为这看起来会更整洁。

于 2013-04-30T17:44:03.753 回答