1

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

В моем файле 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. Официальное лицо AmplitudeJS SDK is here. Я пытаюсь реализовать его через этот wrapper.

AmplitudeService.js (source)

Примечание: Если проверить синтаксис автора, он возвращает объект в конце его службы. В своем исследовании я прочитал, чтобы использовать ключевое слово «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); 
    } 
}]); 

углового amplitude.js (source)

Это позволяет получить доступ к "$" амплитудой на протяжении применения

(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 {}' 
}]) 

Header.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 
}; 
}]); 

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

ответ

0

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

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

0

У нас были похожие проблемы в большом проекте, и мы создали wrapper providing a directive для init Amplitude и службу для предоставления logEvent и sendUserId.