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.

  1. Нажмите на Add Filter,
  2. Дайте вашему фильтру имя.
  3. Установите тип фильтра на Custom,
  4. Выберите include кнопка Установите поле фильтра в Hostname,
  5. Затем установите шаблон так: www\.yourdomain\.com$ (Конечно, если вы не используете ".com", вы используете TLD, который вы фактически используете).
  6. Выберите профили, для которых вы хотите включить этот фильтр.

Это, вероятно, самый простой способ делать то, что вы хотите. Вы отфильтровываете любые данные, которые не из домена.

Другие вопросы по тегам