AngularJS和Google Analytics

RAC*_*RAC 5 javascript google-analytics angularjs

我正在尝试动态更改我的GA跟踪ID(UA-XXXXXXX-X),具体取决于正在查看该页面的环境,但我似乎找不到真正"有角度"的方式来执行此操作.我正在使用Angulartics,但我无法获得基本的GA代码,在Angulartics可以做任何事情之前需要运行.如果我只是将GA代码放在页面底部,它按预期工作,但不是很像Angular,它仍然不允许我动态设置GA ID.

我已经尝试创建一个指令,但是当放入指令的控制器时,跟踪代码似乎没有运行.我创建了一个控制器,它从休息调用中获取环境,然后根据返回的环境分配GA代码,但是当我运行指令时,它运行到早期,GA代码不会触发或触发,而跟踪ID是仍未定义.我还尝试将GA代码放入指令模板中,但出于某种原因,当放在ngAnalytics.html模板内的脚本标记内时,代码根本不会触发,即使我可以看到它在dom中被正确添加到页面中已加载.我是棱角分明的,所以我知道有一个解决方案,但我没有看到它.我的指示如下:

angular.module('ngAnalytics', [])
.directive('ngAnalytics', function( servicesSrvc) {
    return {
        restrict: 'A',
        templateUrl: 'js/directives/ngAnalytics.html',
        controller: ['$scope', function($scope) {
            $scope.trackingID;
            $scope.getEnvDetails = function() {
                var currentEnv = servicesSrvc.getEnv();
                var env;
                currentEnv.then(function(data) {
                    env = JSON.stringify(data.environment);
                    switch(env)
                {
                    case 'local':
                        $scope.trackingID = 'disabled'; // DEV
                        break;
                    case 'dev':
                        $scope.trackingID = 'UA-XXX-X'; // DEV
                        break;
                    ...
                        $scope.trackingID = 'UA-XXX-X'; // Default to dev
                }
                (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', $scope.trackingID, { 'cookieDomain': 'none' }); // For localhost testing
                //ga('create', $scope.trackingID, 'test.com'); // For dev, qa, prod etc...
                //ga('send', 'pageview'); // MUST BE DISABLED when using Angulartics
            });
        }

    }],
    link: function(scope, iElement, iAttrs, ctrl) {

    }
}
});
Run Code Online (Sandbox Code Playgroud)

m59*_*m59 8

我可能会误解你的问题.这听起来像指令架构的一般问题.你正在寻找的是这样的东西吗?现场演示(点击).

<div analytics="trackingId"></div>
Run Code Online (Sandbox Code Playgroud)

JavaScript的:

var app = angular.module('myApp', []);

app.controller('myCtrl', function($scope) {
  //set this however you want, the directive doesn't care - or you can move this into the directive if you want
  //$scope.trackingId = 'UA-XXX-X';
  $scope.trackingId = 'disabled';
});

app.directive('analytics', function() {
  return {
    restrict: 'A',
    scope: {
      id: '=analytics'
    },
    link: function(scope, iElement, iAttrs) {
      (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');

      scope.$watch('id', function(newId, oldId) {
        if (newId) {
          console.log(newId);
          ga('create', scope.id, { 'cookieDomain': 'none' });
        }
      });
    }
  };
});
Run Code Online (Sandbox Code Playgroud)

这里的重要部分是:

scope.$watch('id', function(newId, oldId) {
  if (newId) {
    ga('create', scope.id, { 'cookieDomain': 'none' });
  }
});
Run Code Online (Sandbox Code Playgroud)

这是说只有在有值的情况下才运行该函数,如果scope.id设置或更改了该值,函数将再次运行.我不确定你在做什么servicesSrvc,但你可以使用该服务scope.id从控制器或指令本身进行设置,无论哪种方式,如果你已经设置了$watch,那么当你确定值时,该函数将运行对scope.id.我的回答是基于你的评论,即当值未定义时函数将运行.这就是你如何避免这种情况.

更新

既然你仍然有问题理解这个过程,我已经创建了另一个带有一些console.logs的演示来指导你.在这里演示(点击).

var app = angular.module('myApp', []);

app.factory('myService', function($q, $timeout) {
  var myService = {
    getId: function() {
      var deferred = $q.defer();

      console.log('getting id');
      $timeout(function() {
        //deferred.resolve('UA-XXX-X');
        deferred.resolve('disabled');
      }, 2000);

      return deferred.promise;
    }
  };
  return myService;
});

app.directive('analytics', function(myService) {
  return {
    restrict: 'A',
    link: function(scope, iElement, iAttrs) {
      (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');

      var id;
      scope.$watch(
        function() {
          return id; 
        }, 
        function(newId, oldId) {
          if (newId) {
            console.log('watch is calling function');
            ga('create', newId, { 'cookieDomain': 'none' });
          }
        }
      );

      myService.getId().then(function(response) {
        id = response;
        console.log('id set to ' +response);
      });
    }
  };
});
Run Code Online (Sandbox Code Playgroud)