【问题标题】:Databinding a D3 slider with Knockout使用 Knockout 对 D3 滑块进行数据绑定
【发布时间】:2014-11-17 06:30:28
【问题描述】:

我已经设法创建了一个 D3 滑块(根据之前的一些示例进行了修改),目前我正在尝试将其绑定到 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); 
});

【问题讨论】:

    标签: knockout.js d3.js


    【解决方案1】:

    尝试将滑块的所有逻辑放在幻灯片 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()));
        }
    };
    

    http://jsfiddle.net/v8tvkb4j/

    【讨论】:

    • 很好 - 我需要弄清楚如何实现这一点(因为目前我的可视化会为其自身添加滑块)但您已经完美地演示了该方法。
    猜你喜欢
    • 2015-03-25
    • 2012-04-08
    • 2015-12-28
    • 1970-01-01
    • 2015-01-19
    • 2014-07-24
    • 2016-10-08
    • 2016-12-09
    相关资源
    最近更新 更多