Angularytics (директива Google Analytics для AngularJS) только в производственной среде
Я использую Angularytics в своем веб-приложении AngularJS. Он работает нормально, однако у меня есть три среды (разработка, тестирование и производство), и он собирает статистику по обоим из них. Я хотел бы показать аналитику только для производственной среды.
Я проанализировал много вариантов, но у всех есть некоторые проблемы. Теперь я хотел бы отредактировать скрипт angularytics.js, чтобы добавить условие, поэтому код будет делать что-то только в том случае, если константа $rootScope.ENVIRONMENT имеет значение Production.
Что-то вроде:
(function () {
angular.module('angularytics', []).provider('Angularytics', function () {
if($rootScope.ENVIRONMENT == 'Production') {
var eventHandlersNames = ['Google'];
this.setEventHandlers = function (handlers) {
if (angular.isString(handlers)) {
handlers = [handlers];
}
eventHandlersNames = [];
angular.forEach(handlers, function (handler) {
eventHandlersNames.push(capitalizeHandler(handler));
});
};
var capitalizeHandler = function (handler) {
return handler.charAt(0).toUpperCase() + handler.substring(1);
};
var pageChangeEvent = '$locationChangeSuccess';
this.setPageChangeEvent = function (newPageChangeEvent) {
pageChangeEvent = newPageChangeEvent;
};
this.$get = [
'$injector',
'$rootScope',
'$location',
function ($injector, $rootScope, $location) {
var eventHandlers = [];
angular.forEach(eventHandlersNames, function (handler) {
eventHandlers.push($injector.get('Angularytics' + handler + 'Handler'));
});
var forEachHandlerDo = function (action) {
angular.forEach(eventHandlers, function (handler) {
action(handler);
});
};
var service = {};
service.init = function () {
};
service.trackEvent = function (category, action, opt_label, opt_value, opt_noninteraction) {
forEachHandlerDo(function (handler) {
if (category && action) {
handler.trackEvent(category, action, opt_label, opt_value, opt_noninteraction);
}
});
};
service.trackPageView = function (url) {
forEachHandlerDo(function (handler) {
if (url) {
handler.trackPageView(url);
}
});
};
service.trackTiming = function (category, variable, value, opt_label) {
forEachHandlerDo(function (handler) {
if (category && variable && value) {
handler.trackTiming(category, variable, value, opt_label);
}
});
};
$rootScope.$on(pageChangeEvent, function () {
service.trackPageView($location.url());
});
return service;
}
];
}});
}());
(function () {
angular.module('angularytics').factory('AngularyticsConsoleHandler', [
'$log',
function ($log) {
var service = {};
service.trackPageView = function (url) {
$log.log('URL visited', url);
};
service.trackEvent = function (category, action, opt_label, opt_value, opt_noninteraction) {
$log.log('Event tracked', category, action, opt_label, opt_value, opt_noninteraction);
};
service.trackTiming = function (category, variable, value, opt_label) {
$log.log('Timing tracked', category, variable, value, opt_label);
};
return service;
}
]);
}());
(function () {
angular.module('angularytics').factory('AngularyticsGoogleHandler', function () {
var service = {};
service.trackPageView = function (url) {
_gaq.push([
'_set',
'page',
url
]);
_gaq.push([
'_trackPageview',
url
]);
};
service.trackEvent = function (category, action, opt_label, opt_value, opt_noninteraction) {
_gaq.push([
'_trackEvent',
category,
action,
opt_label,
opt_value,
opt_noninteraction
]);
};
service.trackTiming = function (category, variable, value, opt_label) {
_gaq.push([
'_trackTiming',
category,
variable,
value,
opt_label
]);
};
return service;
}).factory('AngularyticsGoogleUniversalHandler', function () {
var service = {};
service.trackPageView = function (url) {
ga('set', 'page', url);
ga('send', 'pageview', url);
};
service.trackEvent = function (category, action, opt_label, opt_value, opt_noninteraction) {
ga('send', 'event', category, action, opt_label, opt_value, { 'nonInteraction': opt_noninteraction });
};
service.trackTiming = function (category, variable, value, opt_label) {
ga('send', 'timing', category, variable, value, opt_label);
};
return service;
});
}());
(function () {
angular.module('angularytics').filter('trackEvent', [
'Angularytics',
function (Angularytics) {
return function (entry, category, action, opt_label, opt_value, opt_noninteraction) {
Angularytics.trackEvent(category, action, opt_label, opt_value, opt_noninteraction);
return entry;
};
}
]);
}());
Я немного знаю Angular, но думаю, что не достаточно опытен, чтобы внедрить $ rootScope в этот скрипт. Я всегда получаю $rootScope is not defined
,
ОБНОВЛЕНИЕ Что касается комментариев ниже, я обновляю пост: условно добавить скрипт было моим первым подходом. Это может быть сделано в контроллере как:
if ($rootScope.ENVIRONMENT == 'Production') {
var head = document.getElementsByTagName('head')[0];
var js = document.createElement("script");
js.type = "text/javascript";
js.src = "lib/plugins/angularytics-yanpy.js";
head.appendChild(js);
}
Это angularytics-yanpy:
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-59702007-1', 'auto');
С другой стороны, вы должны добавить скрипт angularytics на домашнюю страницу:
I think this will work in production environment. However, now in development a got a javascript error. Because angularytics.js needs the ga object created in the angularytics-yanpy.js. As this script is not created because is in development environment a get the javascript error.
Я также добавил <script src="lib/plugins/angularytics.js"></script>
динамически. Но я получил новую ошибку, потому что этот скрипт определяет провайдера ангулярики, который определен в файле app.js.
Итак, ошибки связаны между собой, и поэтому я попытался обновить скрипт angularytics.js, чтобы сохранить провайдера, но в случае отличия среды от производственной он ничего не должен делать.
Наверное, я не очень понятен, но это нелегко объяснить. Просто дайте мне знать, если вам нужны дополнительные разъяснения.
4 ответа
Вы не должны устанавливать обстановку в $rootScope
, было бы лучше установить его как константу, используя grunt-ng-constant ( см. руководство).
Ответить на ваш вопрос. Вы можете внедрить rootScope в провайдера, используя:
.provider('Angularytics', function ($rootScope) {});
Однако это не хорошее решение вашей общей проблемы.
Хорошим методом было бы определить имя хоста и установить отдельные свойства Google Analytic для:
- развитие
- инсценировка
- производство
В своем HTML-скрипте Google Analytics добавьте этот оператор переключения.
var gaProp;
switch (window.location.hostname) {
case 'www.domain.com':
gaProp = 'UA-123456'; // production
break;
case 'staging.domain.com':
gaProp = 'UA-654321'; // staging
break;
default:
gaProp = 'UA-000000'; // development
}
// Google Analtics
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o), m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', gaProp, 'auto');
Обратите внимание, я устанавливаю gaProp в событии ga (последняя строка).
Таким образом, вы можете установить разные цели и фильтры для каждого свойства, и все ваши тестовые данные не будут мешать друг другу.
Поскольку вы используете Grunt для создания своего приложения, вот метод, который я успешно реализовал в одном из моих приложений на работе.
Я создал 2 кода отслеживания в Google Analytics, один для среды тестирования, другой для производства. Я вижу, что вы не планируете отслеживать свою среду, и это был мой первоначальный план. Однако хорошо проверить, что все работает и в Google Analytics, а также будет очень полезно, если вы начнете отслеживать пользовательские события (например, сколько пользователей нажимают на определенную кнопку и т. Д.). К счастью, коды отслеживания бесплатны...
Я использовал препроцесс Grunt для условного написания соответствующего кода.
В моем index.html
Я разместил свой код GA внизу так:
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
<!-- @if DEV -->
ga('create', 'UA-554030000-1', 'auto');
<!-- @endif -->
<!-- @if PRODUCTION -->
ga('create', 'UA-554030000-2', 'auto');
<!-- @endif -->
</script>
Затем просто настройте вашу задачу:
preprocess : {
html: 'build/index.html',
options: {
inline : true
}
production : {
options: {
context : {
PRODUCTION: true
}
}
},
dev : {
options: {
context : {
DEV: true
}
}
Потом работает grunt preprocess:production
или же grunt preprocess:dev
удалит неиспользуемый код и соберет соответствующий файл. Затем эта задача может быть включена в ваш процесс сборки (я использую флаг как grunt build --dev
направить сценарий на правильный путь).
Это должно быть так же просто, как включить режим разработки, чтобы прекратить отправку информации отслеживания. Прямо из документации написано, что нужно сделать следующее в конфигурации вашего приложения.
Для двух сред вы не хотите, чтобы отслеживание отправлялось, установите значение true, а при переходе в рабочий режим просто установите значение false, используя сценарий сборки.
$analyticsProvider.developerMode(true);
Возможно, вы хотите настроить фильтр в представлениях данных Google Analytics.
- Нажмите на
Add Filter
, - Дайте вашему фильтру имя.
- Установите тип фильтра на
Custom
, - Выберите
include
кнопка Установите поле фильтра вHostname
, - Затем установите шаблон так:
www\.yourdomain\.com$
(Конечно, если вы не используете ".com", вы используете TLD, который вы фактически используете). - Выберите профили, для которых вы хотите включить этот фильтр.
Это, вероятно, самый простой способ делать то, что вы хотите. Вы отфильтровываете любые данные, которые не из домена.