如何使用segment.io's analystics.js在一个敲除自定义绑定中
How to use segment.io's analytics.js in a knockout custom bindings
我正在使用knockout为analytics.track创建自定义绑定,但它似乎遇到了问题。如果analytics.track嵌套在2个以上的函数中,那么track调用似乎会无声地失败。它不会命中回调,也不会在段调试器中报告。我在这里提供了两个例子来证明这个问题:
无关闭(工程):
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);
第1版:另外请注意,如果我将analysis.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立即执行,所以当浏览器遇到iife时,analytics
变量将被设置为window.analytics
是的任何值。在第一种情况下,当代码运行时,将解析window.analytics
。
换句话说:闭包在iife执行时捕获作用域analytics
变量中的window.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>
的确,在我的例子中,第二个场景抛出了一个错误,而你在问题中提到什么都没有发生,但问题中又没有包含实际的repo,所以很难判断差异在哪里。
因此analytics.js在页面中异步加载其自身。与此同时,它将所有对API的调用与对象的怠慢版本一起排队。一旦analytics.js加载,它就会执行队列中的所有调用。然后重新定义它自己,破坏对原始window.analytics的所有引用。因此,我遇到的任何调用都足够快。我唯一的解决办法是让我的exposer成为一个函数调用,返回window.analystics的当前版本。
(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; });
相关文章:
- 将动态元素绑定到函数;只剩下一个绑定
- 如何向onClick事件处理程序传递一个接受参数的函数,并且仍然将该函数绑定到组件's”;这个“;上下文
- 使用react router/react router redux将特定的redux操作绑定到一个路由
- 在dojo中将数据从一个选项卡绑定到另一个选项卡(打开选项卡?)
- 在我的JavaScript模块中绑定一个点击事件
- javascript绑定另一个select2输入字段rails的select2 inputonchange事件的数据
- 在另一个可浏览的应用程序中包含已绑定的文件
- D3.js如何只创建一个绑定到多个数据项的数据集的元素
- 将元素的可见性绑定到另一个元素
- 如果指令包含在另一个指令中,我如何在隔离范围内添加双向数据绑定属性
- 创建一个计算值数组,该数组绑定到AngularJS中的其他输入
- jQuery使用最后一个参数在Javascript循环中单击绑定函数
- 在href跳转到另一个html元素之前,执行Knockout.js数据绑定:点击函数
- 内部有另一个绑定的敲除html绑定
- 从自定义绑定处理程序中更改另一个绑定
- Javascript重新绑定一个绑定函数
- 剑道UI -在另一个绑定中创建绑定
- 多个元素上的动态绑定处理程序将只调用最后一个绑定函数
- 有没有一种方法可以创建一个绑定函数,在数组中提供它的参数?
- 可观察值更新只会改变一个绑定元素,而不会改变另一个