Служба Amplitude AngularJS не действует как синглтон

Я недавно опубликовал аналогичный вопрос, но это не дубликат. Извиняюсь за тяжелый пост с кодом, но я хотел предоставить как можно больше контекста. У меня возникла проблема с определением инструмента аналитики Amplitude в качестве службы в моем приложении Angular.js. Предполагается, что службы действуют как одиночки в приложении (source), поэтому я я смущен, чтобы получить следующее поведение.

В моем файле app.js я вызываю AmplitudeService.logEvent('EVENT_NAME') в функции .run, которая успешно регистрирует событие в Amplitude. Примечание. Console.log(AmplitudeService) возвращает объект со всеми правильными функциями.

Однако, когда я вызываю AmplitudeService.logEvent('EVENT_NAME') в любом другом контроллере, таком как header.js, я никогда не вижу никаких данных на панели инструментов Amplitude. Примечание. Console.log(AmplitudeService) возвращает в header.js объект, идентичный объекту, возвращаемому из app.js.

Буду признателен за любое понимание!

P.S. Официальный SDK AmplitudeJS находится здесь. Я пытаюсь реализовать это через эту оболочку.

AmplitudeService.js (источник)

Примечание. Если вы проверите синтаксис автора, он вернет объект в конце своей службы. В своем исследовании я читал об использовании ключевого слова this при определении функций службы (source), и что вам не нужно возвращать объект, как в случае с Factory, поэтому я обновил его соответствующим образом.

angular.module('AmplitudeService', [])
.service('AmplitudeService', 
['$amplitude', '$rootScope', 'amplitudeApiKey', '$location',
function ($amplitude, $rootScope, amplitudeApiKey, $location) {

  this.init = function() {
    $amplitude.init(amplitudeApiKey, null);
  }

  this.identifyUser = function(userId, userProperties) {
    $amplitude.setUserId(userId);
    $amplitude.setUserProperties(userProperties);
  }

  this.logEvent = function(eventName, params) {
    $amplitude.logEvent(eventName, params);
  }
}]);

angular-amplitude.js (источник)

Это позволяет получить доступ к «$ amplitude» во всем приложении.

(function(){
var module = angular.module('angular-amplitude', ['ng']);

module.provider('$amplitude', [function $amplitudeProvider() {
this.$get = ['$window', function($window) {
  (function(e,t){
    var r = e.amplitude || {};
    var n = t.createElement("script");
    n.type = "text/javascript";
  n.async = true;
  n.src = "https://d24n15hnbwhuhn.buttfront.net/libs/amplitude-2.2.0-min.gz.js";
  var s = t.getElementsByTagName("script")[0];
  s.parentNode.insertBefore(n,s);
  r._q = [];

  function a(e){
    r[e] = function(){
      r._q.push([e].concat(Array.prototype.slice.call(arguments,0)));
    }
  }
  var i =    ["init","logEvent","logRevenue","setUserId","setUserProperties","setOptOut","setVersionName","setDomain","setDeviceId","setGlobalUserProperties"];
  for(var o = 0; o < i.length; o++){
    a(i[o])
  }
  e.amplitude = r
}
  )(window,document);
  return $window.amplitude;
}];
}]);
return module;
}());

App.js

angular.module('app', [
'ngRoute',
'angular-amplitude',
'AmplitudeService',
])

 .run(['AmplitudeService', function(AmplitudeService){
 console.log(AmplitudeService); // Outputs 'Object {}'
 AmplitudeService.init();
 *AmplitudeService.logEvent('LAUNCHED_SITE'); // This logs the event*
 console.log(AmplitudeService); // Outputs 'Object {}'
 }])

Заголовок.js

  angular.module('app.common.header', [])
 .controller('HeaderCtrl', [ '$rootScope', '$scope', '$location','$route', '$window', 'AmplitudeService', function($rootScope, $scope, $location, $route, $window, AmplitudeService){

 $scope.goToSearch = function(term) {
 $location.path('/search/' + term);
  console.log(AmplitudeService); // Outputs 'Object {}'
*AmplitudeService.logEvent('SEARCHED');* // This does not log the event
 };
 }]);

Обновление: я попытался переключить службу на фабрику, и это не дало никаких новых результатов.


person zcoon    schedule 24.05.2016    source источник


Ответы (2)


Нашел решение и надеюсь, что это полезно для всех, кто сталкивается с этим. Мое решение состояло в том, чтобы инициализировать SDK, вызвав AmplitudeService.init() внутри функции .run() в app.js, которая инициализировала объект амплитуды в моем окне. С этого момента я включил $window в качестве службы в каждый из моих контроллеров и вызвал $window.amplitude.logEvent('event_name_here');

Не стесняйтесь обращаться, если у вас есть вопросы. Спасибо.

person zcoon    schedule 24.05.2016

У нас были похожие проблемы в большом проекте, и мы создали оболочку, предоставляющую директиву для инициализации Amplitude и сервис для предоставления logEvent и sendUserId.

person Gregori    schedule 29.06.2016