AngularJS Amplitude Service не действует как синглтон
Я недавно опубликовал похожий вопрос, но это не дубликат. Извиняюсь за тяжелый пост кода, но я хотел предоставить как можно больше контекста. У меня возникла проблема с определением инструмента аналитики "Amplitude" как службы в моем приложении Angular.js. Службы должны действовать как синглтоны в приложении ( источнике), поэтому я не понимаю, как поступить следующим образом.
В моем файле 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.
Был бы признателен любой и все понимание!
PS Официальный SDK AmplitudeJS здесь. Я пытаюсь реализовать это через эту оболочку.
AmplitudeService.js ( источник)
Примечание. Если вы проверите синтаксис автора, он возвращает объект в конце своего сервиса. В своем исследовании я прочитал, чтобы использовать ключевое слово "this" при определении служебных функций ( источника) и что вам не нужно возвращать объект, как это было бы с фабрикой, поэтому я обновил его соответствующим образом.
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-амплитуд.js ( источник)
Это позволяет получить доступ к "$ амплитуде" во всем приложении
(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
};
}]);
Обновление: я попытался переключить Сервис на Фабрику, и это не привело к новым результатам.
2 ответа
Нашел решение и надеюсь, что это пригодится всем, кто с этим сталкивается. Моим решением было инициализировать SDK, вызвав AmplitudeService.init() внутри функции.run() в app.js, которая инициализировала объект амплитуды в моем окне. После этого я включил $window в качестве службы в каждый из моих контроллеров и назвал $window.amplitude.logEvent('event_name_here');
Не стесняйтесь обращаться, если у вас есть вопросы. Благодарю.
У нас были похожие проблемы в большом проекте, и мы создали оболочку, предоставляющую директиву init Amplitude и сервис для предоставления logEvent и sendUserId.