Angularytics(Google Analytics for AngularJS directive)仅在生产环境中
Angularytics (Google Analytics for AngularJS directive) only in production environment
我在 AngularJS 网络应用程序中使用 Angularytics。它工作正常,但是,我有三个环境(开发、测试和生产),并且它从这两个环境收集统计数据。我只想显示生产环境的分析。
我分析了很多方案,但都存在一些问题。现在,我想编辑 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
.
更新
关于下面的评论,我更新post:
有条件地添加脚本是我的第一种方法。这可以在控制器中完成,例如:
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 提供程序。
所以,错误是连锁的,这就是为什么我试图更新 angularytics.js 脚本以保留提供者,但如果环境不同,生产它应该什么都不做。
可能我不是很清楚,但也不好解释。如果您需要更多说明,请告诉我。
您可能想在 Google Analytics 数据视图中设置过滤器。
- 单击
Add Filter
。
- 为您的过滤器命名。
- 将过滤器类型设置为
Custom
。
- Select
include
按钮将筛选字段设置为 Hostname
。
- 然后像这样设置模式:
www\.yourdomain\.com$
(当然如果
您不使用“.com”,而是使用您实际使用的 TLD。
- Select 您要为其启用此过滤器的配置文件。
这可能是执行您想要的操作的最简单方法。您过滤掉所有不是来自该域的数据。
您不应该在 $rootScope
中设置环境,最好使用 grunt-ng-constant (see tutorial).
将其设置为常量
回答你的问题。您可以使用以下方法将 rootScope 注入提供程序:
.provider('Angularytics', function ($rootScope) {});
但是这不是解决您的整体问题的好方法。
一个好的方法是检测主机名并设置单独的 Google 分析属性 for:
- 发展
- 分期
- 制作
在您的 html google 分析脚本中添加此 switch 语句。
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');
注意我在 ga 事件中设置 gaProp(最后一行)。
这样您就可以为每个 属性 设置不同的目标和过滤器,并且您的所有测试数据都不会相互干扰。
当您使用 Grunt 构建您的应用程序时,这是我在工作中的一个应用程序中成功实施的方法。
我在 Google Analytics 中生成了 2 个跟踪代码,一个用于 testing 环境,一个用于 production。我看到你不打算跟踪你的环境,这也是我最初的计划。然而,测试关于 Google Analytics 的一切是否正常也是很好的,而且如果您开始跟踪自定义事件(例如有多少用户点击某个按钮等),它也将非常有用。幸运的是跟踪代码是免费的...
我已经使用 Grunt preprocess 有条件地编写了适当的代码。
在我的 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);
我在 AngularJS 网络应用程序中使用 Angularytics。它工作正常,但是,我有三个环境(开发、测试和生产),并且它从这两个环境收集统计数据。我只想显示生产环境的分析。
我分析了很多方案,但都存在一些问题。现在,我想编辑 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
.
更新 关于下面的评论,我更新post: 有条件地添加脚本是我的第一种方法。这可以在控制器中完成,例如:
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 提供程序。
所以,错误是连锁的,这就是为什么我试图更新 angularytics.js 脚本以保留提供者,但如果环境不同,生产它应该什么都不做。
可能我不是很清楚,但也不好解释。如果您需要更多说明,请告诉我。
您可能想在 Google Analytics 数据视图中设置过滤器。
- 单击
Add Filter
。 - 为您的过滤器命名。
- 将过滤器类型设置为
Custom
。 - Select
include
按钮将筛选字段设置为Hostname
。 - 然后像这样设置模式:
www\.yourdomain\.com$
(当然如果 您不使用“.com”,而是使用您实际使用的 TLD。 - Select 您要为其启用此过滤器的配置文件。
这可能是执行您想要的操作的最简单方法。您过滤掉所有不是来自该域的数据。
您不应该在 $rootScope
中设置环境,最好使用 grunt-ng-constant (see tutorial).
回答你的问题。您可以使用以下方法将 rootScope 注入提供程序:
.provider('Angularytics', function ($rootScope) {});
但是这不是解决您的整体问题的好方法。
一个好的方法是检测主机名并设置单独的 Google 分析属性 for:
- 发展
- 分期
- 制作
在您的 html google 分析脚本中添加此 switch 语句。
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');
注意我在 ga 事件中设置 gaProp(最后一行)。
这样您就可以为每个 属性 设置不同的目标和过滤器,并且您的所有测试数据都不会相互干扰。
当您使用 Grunt 构建您的应用程序时,这是我在工作中的一个应用程序中成功实施的方法。
我在 Google Analytics 中生成了 2 个跟踪代码,一个用于 testing 环境,一个用于 production。我看到你不打算跟踪你的环境,这也是我最初的计划。然而,测试关于 Google Analytics 的一切是否正常也是很好的,而且如果您开始跟踪自定义事件(例如有多少用户点击某个按钮等),它也将非常有用。幸运的是跟踪代码是免费的...
我已经使用 Grunt preprocess 有条件地编写了适当的代码。
在我的 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);