Я использую angularjs $log в chrome, но он показывает строку вроде: angular.js: 9037, я хочу показать номер строки, где я вызываю этот метод (показать мое имя js и правильную строку), Кто-нибудь знает это? или angular не имеет этой функции.
Angularjs $log - показать номер строки
Ответ 1
В Chrome есть функция Blackboxing. Вы можете использовать его для исключения/обхода (библиотеки) источников из сеансов отладки или рабочего процесса разработки.
Итак, если вы используете blackbox angular, внутренние службы $log обходятся, а консоль печатает правильный номер строки!
Ответ 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);
}
};
}