繁体   English   中英

如何在淘汰定制绑定中使用segment.io的analytics.js

[英]How to use segment.io's analytics.js in a knockout custom bindings

我正在使用淘汰赛为analytics.track进行自定义绑定,但似乎遇到了麻烦。 如果analytics.track嵌套在两个以上的函数中,则跟踪调用会以静默方式失败。 它不会触发回调,也不会在段调试器中报告。 我提供了2个示例来演示此问题:

不关闭(有效):

function sendTrack(event, props) {
  console.log("Enter sendTrack");
  analytics.track('Signed Up', {
    plan: 'Enterprise'
  }, {}, function () {
    console.log('track callback logged');
  });
}

ko.bindingHandlers.segmentTrack = {
  init: function (element, valueAccessor) {
    console.log("Init");
    var value = ko.unwrap(valueAccessor());
    ko.applyBindingsToNode(element, { click: sendTrack });
  }
};
ko.applyBindings({});

有关闭功能(无效):

(function(ko, $, analytics){
  'use strict';
  function sendTrack(event, props) {
    console.log("Enter sendTrack");
    analytics.track('Signed Up', {
      plan: 'Enterprise'
      }, {}, function () {
        console.log('track callback logged');
      });
  }

  ko.bindingHandlers.segmentTrack = {
    init: function (element, valueAccessor) {
      console.log("Init");
      var value = ko.unwrap(valueAccessor());
      ko.applyBindingsToNode(element, { click: sendTrack });
    }
  };

  ko.applyBindings({});
})(window.ko, window.jQuery, window.analytics);

Edit1:另外请注意,如果我将analytics.track移至init,则此方法适用:

(function(ko, $, analytics){
  'use strict';
  ko.bindingHandlers.segmentTrack = {
    init: function (element, valueAccessor) {
      console.log("Init");
      analytics.track('Signed Up', {
      plan: 'Enterprise'
      }, {}, function () {
        console.log('track callback logged');
      });
    }
  };

  ko.applyBindings({});
})(window.ko, window.jQuery, window.analytics);

请指教

这很可能是由于在window对象上加载/初始化事物的顺序。 由于iife 立即执行,因此将analytics变量设置为任何window.analytics ,即浏览器遇到iife的那一刻 在第一种情况下, 运行代码时将解析window.analytics

换句话说:闭包在执行iife时将捕获的window.analytics捕获到作用域analytics变量

这是演示问题的演示。

不关闭:

 function sendTrack() { console.log("Tracking..."); analytics.track("stuff"); } ko.bindingHandlers.segmentTrack = { init: function(element) { console.log("Init"); ko.applyBindingsToNode(element, { click: sendTrack }); } } ko.applyBindings({ }); // Simulate loading analytics now: window.analytics = { track: function(txt) { console.log("Tracking " + txt); } }; 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script> <div data-bind="segmentTrack: true">CLICK ME</div> 

与闭包:

 (function(ko, analytics) { function sendTrack() { console.log("Tracking..."); analytics.track("stuff"); } ko.bindingHandlers.segmentTrack = { init: function(element) { console.log("Init"); ko.applyBindingsToNode(element, { click: sendTrack }); } } ko.applyBindings({}); })(window.ko, window.analytics); // window.analytics isn't quite okay yet! // Simulate loading analytics now: window.analytics = { track: function(txt) { console.log("Tracking " + txt); } }; 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script> <div data-bind="segmentTrack: true">CLICK ME</div> 

没错,在我的示例中,第二种情况引发了错误,而您在问题中提到没有任何反应 ,但是问题又没有包含实际的再现性,因此很难分辨出差异所在。

因此,analytics.js将自己的自身异步加载到页面中。 同时,它会将对象的缓冲版本将所有对API的调用排队。 analytics.js加载后,将执行队列中的所有调用。 然后重新定义其自身,将所有引用都破坏到原始window.analytics。 因此,对于我而言,足够快地遇到的所有调用都只能解决,这是使我的暴露函数成为一个函数调用,该函数调用返回window.analytics的当前版本。

(function (ko, $, analytics) {

    function sendTrack(event, props) {
        analytics().track(event, props);
    }

    ko.bindingHandlers.segmentTrack = {
        init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
            var value = ko.unwrap(valueAccessor());
            ko.applyBindingsToNode(element, { click: function () { sendTrack(value.event, value.options) }});
        }
    }
})(window.ko, window.jQuery, function () { return window.analytics; });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM