我设法创建了一个D3滑块(从之前的一些示例中进行了修改),此刻我试图将其绑定到Knockout。我的最终用例需要同时在屏幕上显示大量滑块,并且能够通过下面的计算引擎修改值 - knockout应该提供一种很好的方法。
我的问题是试图弄清楚如何将对象数据绑定在一起,我计划使用一些自定义绑定,但无法弄清楚如何实际获取我的对象。我的滑块的简短代码示例:
custom.d3.slider = function () {
var slider = { };
var value;
slider.value = function (_) {
if (!arguments.length) return value;
_update(_);
return slider;
};
slider.appendTo = function (target) {
var sliderBar = target.append("g")
.attr("class", "slider " + cssClass)
.attr("data-bind", "slide: 0.5")
.attr("transform", "translate(" + margin.left + ", " + margin.top + ")")
.call(d3.svg.axis()
.scale(xScale)
.tickSize(0) // ensure that end ticks are not displayed
.ticks([])) // ensure that no ticks are included in the DOM
.select(".domain") // this is a custom class added by D3
.select(function () {
return this.parentNode.appendChild(this.cloneNode(true));
})
.attr("class", "inner-bar")
.select(function () {
return this.parentNode.appendChild(this.cloneNode(true));
})
.attr("class", "fill-bar");
};
return slider;
}
所以在此之后我想设置我的自定义绑定,我现在用调试器语句定义了以下绑定,试着看看发生了什么:
ko.bindingHandlers.slide = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var d = d3.select(element);
debugger;
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var d = d3.select(element);
debugger;
}
};
这让我得到了我认为是D3对象(而不是DOM对象):
我无法弄清楚的问题是,如何从这里实际访问我的slider.value()
功能。甚至可能这样做,还是我以错误的方式解决这个问题? JSFiddle example
我已经设法获得了一个解决方案JSFiddle here,但它只是觉得做错的方法,即手动更新视图模型并订阅事件:
slider.callback(function(context, value) {
vm.myVal(value);
console.log(context.value());
});
var vm = {
myVal: ko.observable(0.5)
};
vm.myVal.subscribe(function(v) {
slider.value(v);
});
答案 0 :(得分:1)
尝试将滑块的所有逻辑放在slide bindingHandler中。您的init应该实例化一个新的滑块,更新应该更新滑块的值,例如:
ko.bindingHandlers.slide = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var valueObservable = valueAccessor();
element.__slider__ = custom.d3.slider()
.configure({
minimumValue: 0,
maximumValue: 1,
value: 0.5
})
.margin({ top: 20, left: 40})
.appendTo(element)
.callback(function (context, value) {
valueObservable(context.value());
});
// or when you're using jQuery, use the .data function to store the
// slider instance: $(element).data('slider', ...);
},
update: function(element, valueAccessor) {
element.__slider__.value(ko.unwrap(valueAccessor()));
}
};