Подтвердить что ты не робот

Angularjs $log - показать номер строки

Я использую angularjs $log в chrome, но он показывает строку вроде: angular.js: 9037, я хочу показать номер строки, где я вызываю этот метод (показать мое имя js и правильную строку), Кто-нибудь знает это? или angular не имеет этой функции.

4b9b3361

Ответ 1

В Chrome есть функция Blackboxing. Вы можете использовать его для исключения/обхода (библиотеки) источников из сеансов отладки или рабочего процесса разработки.

Итак, если вы используете blackbox angular, внутренние службы $log обходятся, а консоль печатает правильный номер строки!

https://developer.chrome.com/devtools/docs/blackboxing

Ответ 2

Вы можете получить к нему доступ, применив декоратор к службе $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) 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: MDN говорит, что Error.prototype.stack является нестандартным (требует IE10 и может не поддерживаться во многих мобильных браузерах), поэтому вы можете посмотреть на увеличение это с чем-то вроде stacktracejs, чтобы получить сам стек.

Ответ 3

Я объединил пару решений с этой страницы, а также другие, чтобы создать простую демонстрацию в JSFiddle - продемонстрировать использование службы $log, улучшив ее с помощью декораторов, чтобы добавить номер строки (номер строки, из которой $log call был сделал). Я также сделал несколько более комплексное решение в Plunker, продемонстрировав использование службы $log, улучшив его с помощью декораторов, чтобы добавить номер строки, имя файла вызывающего абонента и имя экземпляра. Надеюсь, это будет полезно для других.

URL-адрес JSFiddle - https://jsfiddle.net/abhatia/6qnz0frh/

Эта скрипка была протестирована со следующими браузерами:

  • IE 11 - (JSFiddle номер первой строки Javascript - 72).
  • Firefox 46.0.1 - (номер первой строки JSFiddle Javascript - 72).
  • Chrome 50.0.2661.94 м - (номер первой строки JSFiddle Javscript равен 71).

Результаты хорошие. Обратите внимание, что номер строки в Chrome будет отключен на 1 по сравнению с FF или IE, т.е. Поскольку номер первой строки кода JSFiddle javascript отличается между FF/IE и Chrome, как указано выше.

URL-адрес плунжера - https://embed.plnkr.co/YcfJ7V/

Этот плунк демонстрирует концепцию очень хорошо, с подробным объяснением, а также предоставляет вывод на консоль с официальным примером службы $log по умолчанию Angular, поэтому их можно было бы противопоставить. Plunk также был протестирован с браузерами, перечисленными выше.

Ниже снимок экрана - это вывод консоли из приведенного выше примера Plunk. Есть 3 выделенные области:

  • В красном поле отображается вывод консоли с использованием службы $log $default. $log, вызванные с контроллера.
  • В синем поле отображается консольный вывод с использованием расширенного сервиса $log. $log, вызываемые контроллером. Вы можете увидеть, как отображаются имена и номера строк script, а также имя контроллера (используется при создании журнала $log).
  • Оранжевая коробка контрастирует с консольным выходом по умолчанию и расширяет сервисы $log.

Журнал консоли из вывода плунжера

Это станет очень понятным при просмотре кода Plunk.

Вот функция getLineNumber, используемая в JSFiddle (в немного улучшенной версии используется пример 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; 
}

Ответ 4

Номер строки поступает из среды выполнения. Вы не можете установить его в общем случае.

Но не все потеряно. В тех местах, где номер строки действительно важен, вы можете использовать другой вызов. Не забудьте ввести $window, а затем:

$window.console.log("test1");

Вы теряете некоторые вещи таким образом, как форматирование, код перекрестных броузеров и т.д., но вы действительно получаете номера строк бесплатно без какого-либо определенного кода выполнения, чтобы сделать это.

Ответ 5

Близко к плагиат-ловушку

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

Ответ 6

Я использовал решение floatingLomas с некоторыми настройками, поскольку он не совсем работает на FF, стек немного отличается. И фантомы, подобные IE, не поддерживают Error.stack и взрываются. Расположение журнала можно щелкнуть в хроме, но не в 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) 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);
        }
    };
}